banner
cells

cells

为美好的世界献上 bug

TCP

TCP/IP 协议三次握手(Three Way Handshake)#

三次握手是用于建立客户端与服务器的 TCP 连接,确保连接是可靠的、同步的。

  1. 第一次握手:SYN

    • 客户端向服务器发送一个 SYN(Synchronize)报文,表示请求建立连接。
    • 客户端进入 SYN-SENT 状态,等待服务器响应。
    客户端 - SYN ---> 服务器
    
  2. 第二次握手:SYN-ACK

    • 服务器受到客户端的 SYN 报文后,回应一个 SYN-ACK(Synchronize Acknowledge)报文,表示接受并同意建立连接,同时也向客户端发送一个 SYN,请求建立反向连接。
    • 服务器进入 SYN-RECEIVED 状态。
    客户端 <--- SYN-ACK - 服务器
    
  3. 第三次握手:ACK

    • 客户端收到服务器的 SYN-ACK 报文后,发送一个确认 ACK 报文,表示连接已建立。
    • 客户端进入 ESTABLISHED 状态,服务器收到 ACK 后也进入 ESTABLISHED 状态。
    客户端 - ACK ---> 服务器
    

三次握手的目的#

确保双方能正确发送和接收数据,并同步双方的序列号。

解释 TCP 需要三次握手的原因#

三次握手是为了确保双方都有发送和接收的能力(双方都要确认对方有发送和接收的能力)。

  • 第一次握手:客户端告诉服务器,自己可以发送数据。
  • 第二次握手:服务器告诉客户端,自己可以收发数据。
  • 第三次握手:客户端告诉服务器,自己可以接收数据。

TCP/IP 协议四次挥手(Four Way Handshake)#

四次回收用于断开客户端与服务器的连接,由于 TCP 是全双工协议,连接断开时需要双方各自关闭发送和接收通道,因此需要四次挥手来完成断开操作。

  1. 第一次挥手:FIN

    • 客户端发送 FIN(Finish)报文,表示不再发送数据,但仍可以接收数据。
    • 客户端进入 FIN-WAIT-1 状态。
    客户端 - FIN ---> 服务器
    
  2. 第二次挥手:ACK

    • 服务器受到客户端的 FIN 报文后,发送一个 ACK 报文,表示确认受到 FIN 报文,但服务器仍可能有数据需要发送。
    • 服务器进入 CLOSE-WAIT 状态,客户端进入 FIN-WAIT-2 状态。
    客户端 <--- ACK - 服务器
    
  3. 第三次挥手:FIN

    • 服务器完成数据发送后,向客户端发送 FIN 报文,表示数据传输结束,准备关闭连接。
    • 服务器进入 LAST-ACK 状态。
    客户端 <--- FIN - 服务器
    
  4. 第四次挥手:ACK

    • 客户端收到服务的 FIN 报文后,发送一个 ACK 报文,表示确认关闭连接。
    • 客户端进入 TIME-WAIT 状态,等待一段时间(一般为 2 * MSL,最大报文存活时间)后,正式关闭连接,进入 CLOSED 状态。服务器在收到 ACK 后立即进入 CLOSED 状态。
    客户端 - ACK ---> 服务器
    

简述 TCP 拥塞控制算法#

  • 慢启动:建立连接后,初始化发送窗口大小,随着每次发送 ACK 到达,窗口大小呈指数级增长,直到达到拥塞阀值。
  • 拥塞避免:当窗口大小达到阀值后,发送方每次只增加一个 MSS。
  • 快速重传:在没有等待超时的情况下,接收方连续发送 3 个重复的 ACK 时,发送方立即重传相应的报文段。
  • 快速恢复:当进入快速重传阶段后,发送方将窗口减半。

简述 MTU 和 MSS#

MTU(Maximum Transmission Unit):最大传输单元,表示网络层一次能传输的最大数据包大小,以太网通常为 1500 Byte。

MSS(Maximum Segement Size):最大报文段大小,TCP 层能够发送的单个数据段的最大字节数,通常是 MTU 减去 TCP/IP 头部大小。

TCP 粘包问题#

当客户端发送多个数据包给服务器时,服务器底层的 TCP 接收缓冲区受到的数据为粘在一起的。

TCP 底层通信是面向字节流的,面向连接的协议,TCP 保证发送数据的准确性和顺序性,字节流以字节为单位。

假设 TCP 缓冲区的大小为 10 个字节,当发送 4 个字节的数据("aaaa"),缓冲区还剩余 6 个字节的空闲空间,再次发送 7 个字节的数据("bbbbbbc"),则客户端第一次接收的数据是 "aaaabbbbbb" ,剩余 1 个字节的数据未发送,等待下一次发送。

TCP 粘包产生的原因#

多个小数据包在传输过程中粘在一起,接收端无法区分这些包的边界,导致接收到的数据合并在一起。

  1. (发的太快)当客户端的发送频率远高于服务器的接收频率。
  2. (发的太少)TCP 底层的安全和效率机制,其不允许字节数特别少的小包发送频率过高,TCP 会在底层累计到一定大小才一起发送。(Nagle
  3. (缓冲区残留)发送端的缓冲区中有上一次未发送完的数据,或接收端的缓冲区中有未取出的数据。

TCP 黏包处理的方式#

主要采用应用层定义收发包格式的方法,俗称切包处理

使用 TLV 协议#

TLV(Type Length Value)协议。

+---------+---------+---------+
|  type   |  length |  value  |
+---------+---------+---------+

打包发送的数据,解包接收的数据。

使用分隔符#

在报文之间增加特殊字符

设置固定长度的报文#

规定报文的长度,接收方根据长度拆分。

TCP 实现全双工的方式#

  1. 独立的发送和接收缓冲区,通信双方都有一个发送缓冲区和接收缓冲区,通信双方在发送数据时可以接收数据,反之依然。
  2. 独立的序列号和确认机制,TCP 将要发送的数据流切分为多个报文段,每个报文段的字节都有唯一的序列号,确保发送的数据包在整个数据流中的位置,接收方可以根据序列号判断数据的正确顺序以及是否有丢包。
  3. 流量控制,TCP 通过控制滑动窗口机制调整发送速率,保证不会让接收方的缓冲区溢出(被数据淹没)。
  4. 拥塞控制,控制通过调节发送方的发送速率来防止网络过载。
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。