TCP粘包问题的产生
由于TCP协议是基于字节流并且无边界的传输协议, 因此很有可能产生粘包问题。此外,发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一个TCP段。若连续几次需要send的数据都很少,通常TCP会根据优化算法把这些数据合成一个TCP段后一次发送出去,但是接收方并不知道要一次接收多少字节的数据,这样接收方就收到了粘包数据。具体可以见下图:
假设主机A send了两条消息M1和M2 各10k 给主机B,由于主机B一次提取的字节数是不确定的,接收方提取数据的情况可能是:
• 一次性提取20k 数据• 分两次提取,第一次5k,第二次15k
• 分两次提取,第一次15k,第二次5k
• 分两次提取,第一次10k,第二次10k(仅此正确)
• 分三次提取,第一次6k,第二次8k,第三次6k
• 其他任何可能
粘包问题产生的多种原因:
1、SQ_SNDBUF 套接字本身有缓冲区大小的限制 (发送缓冲区、接受缓冲区)
2、TCP传送的端 MSS大小限制
3、链路层也有MTU大小限制,如果数据包大于>MTU要在IP层进行分片,导致数据分割。
4、TCP的流量控制和拥塞控制,也可能导致粘包
5、文章开始提到的TCP延迟确认机制等
注: 关于MTU和MSS
MSS指的是TCP中的一个概念。MTU是一个没有固定到特定OSI层的概念,不受其他特定协议限制。也就是说第二层会有MTU,第三层会有MTU,像MPLS这样的第2.5层协议,也有自己的MTU值。并且不同层之间存在关联关系。<