1.什么是粘包现象?
TCP粘包是指发送方发送的若干数据到接收方时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
2.为什么会出现粘包现象?
(1)发送方原因
我们知道,TCP默认会使用Nagle算法。而Nagle算法主要做两件事:1)只有上一个分组得到确认,才会发送下一个分组;2)收集多个小分组,在一个确认到来时一起发送。
所以,正是Nagle算法造成了发送方有可能造成粘包现象。
(2)接收方原因
TCP接收到分组时,并不会立刻送至应用层处理,或者说,应用层并不一定会立即处理;实际上,TCP将收到的分组保存至接收缓存里,然后应用程序主动从缓存里读收到的分组。这样一来,如果TCP接收分组的速度大于应用程序读分组的速度,多个包就会被存至缓存,应用程序读时,就会读到多个首尾相接粘到一起的包。
3.什么时候要处理粘包现象
(1)如果发送方发送的多个分组本来就是同一个数据的不同部分,比如一个很大的文件被分成多个分组发送,这时,当然不需要处理粘包的现象;
(2)但如果多个分组本毫不相干,甚至是并列的关系,我们就一定要处理粘包问题了。比如,我当时要接收的每个分组都是一个有固定格式的商品信息,如果不处理粘包问题,每个读进来的分组我只会处理最前边的那个商品,后边的就会被丢弃。这显然不是我要的结果。
3.1 如何处理粘包现象
- 发送方
对于发送方造成的粘包现象,我们可以通过关闭Nagle算法来解决,使用TCP_NODELAY选项来关闭Nagle算法。 - 接收方
遗憾的额是TCP并没有处理粘包现象的机制,我们只能在应用层处理。 - 应用层处理
- 格式化数据:每条数据有固定的格式(开始符、结束符),这种方法简单易行,但选择开始符和结束符的时候一定要注意每条数据的内部一定不能出现开始符或结束符;
- 发送长度:发送每条数据的时候,将数据的长度一并发送,比如可以选择每条数据的前4位是数据的长度,应用层处理时可以根据长度来判断每条数据的开始和结束。
4. 知乎关于粘包的讨论
-
怎么解决TCP网络传输“粘包”问题? - 谢狄的回答 - 知乎
https://www.zhihu.com/question/20210025/answer/358326299 -
怎么解决TCP网络传输“粘包”问题? - edwinfound的回答 - 知乎
https://www.zhihu.com/question/20210025/answer/711694003