什么是 TCP 粘包和拆包?

TCP 粘包和拆包
假设客户端分别发送了两个数据包 D1 和 D2 给服务端,由于服务端一次读取到的字节数是不确定的,故可能存在以下 4 种情况。
服务端分两次读取到了两个独立的数据包,分别是 D1 和 D2,没有粘包和拆包;
服务端一次接收到了两个数据包,D1 和 D2 粘合在一起,被称为 TCP 粘包;
服务端分两次读取到了两个数据包,第一次读取到了完整的 D1 包和 D2 包的部分内容,第二次读取到了 D2 包的剩余内容,这被称为 TCP 拆包;
服务端分两次读取到了两个数据包,第一次读取到了 D1 包的部分内容 D1_1,第二次读取到了 D1 包的剩余内容 D1_2 和 D2 包的整包。
如果此时服务端 TCP 接收滑窗非常小,而数据包 D1 和 D2 比较大,很有可能会发生第五种可能,即服务端分多次才能将 D1 和 D2 包接收完全,期间发生多次拆包。
TCP粘包/拆包发生的原因
应用程序 write 写入的字节大小大于套接口发送缓冲区大小;
进行 MSS 大小的 TCP 分段;
以太网帧的 payload 大于 MTU 进行 IP 分片。
MTU
泛指通讯协议中的最大传输单元。一般用来说明TCP/IP四层协议中数据链路层的最大传输单元,不同类型的网络MTU也会不同,我们普遍使用的以太网的MTU是1500,即最大只能传输1500字节的数据帧。可以通过ifconfig命令查看电脑各个网卡的MTU。
MSS
指TCP建立连接后双方约定的可传输的最大TCP报文长度,是TCP用来限制应用层可发送的最大字节数。如果底层的MTU是1500byte,则 MSS = 1500- 20(IP Header) -20 (TCP Header) = 1460 byte。
- Post title:什么是 TCP 粘包和拆包?
- Post author:xxxixxxx
- Create time:2021-02-14 11:50:00
- Post link:https://xxxixxx.github.io/2021/02/14/1000-011什么是 TCP 粘包和拆包?/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
Comments