什么是TCP粘包以及如何处理?UDP有粘包吗?
- 1.什么是TCP粘包
- 2. 出现粘包的原因
-
- 2.1 发送方原因
- 2.2 接收方原因
- 3. 粘包的处理
-
- 3.1 什么时候需要处理
- 3.2 如何处理
- 4. UDP没有粘包
1.什么是TCP粘包
TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包,从接收缓冲区来看,后一包数据的头紧接着前一包数据的尾,出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方。
2. 出现粘包的原因
出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方。
2.1 发送方原因
TCP默认使用Nagle算法(主要作用:减少网络中报文段的数量)
Nagle算法主要做两件事:
- 只有上一个分组得到确认,才会发送下一个分组
- 收集多个小分组,在一个确认到来时一起发送
Nagle算法造成了发送方可能会出现粘包问题。
Negale 算法是指发送方发送的数据不会立即发出,而是先放在缓冲区, 等缓存区满了再发出。发送完一批数据后, 会等待接收方对这批数据的回应,然后再发送下一批数据。Negale 算法适用于发送方需要发送大批量数据, 并且接收方会及时作出回应的场合, 这种算法通过减少传输数据的次数来提高通信效率.
2.2 接收方原因
TCP接收到数据包时,并不会马上交到应用层进行处理,或者说应用层并不会立即处理。实际上,TCP将接收到的数据包保存在接收缓存里,然后应用程序主动从缓存读取收到的分组。这样一来,如果TCP接收数据包到缓存的速度大于应用程序从缓存中读取数据包的速度,多个包就会被缓存,应用程序就有可能读取到多个首尾相接粘到一起的包。
3. 粘包的处理
3.1 什么时候需要处理
如果发送方发送的多组数据本来就是同一块数据的不同部分,比如说一个文件被分成多个部分发送,这时当然不需要处理粘包现象
如果多个分组毫不相干,甚至是并列关系,这个时候就一定要处理粘包现象了。
3.2 如何处理
-
发送方
对于发送方造成的粘包问题,可以通过关闭Nagle算法来解决,使用TCP_NODELAY选项来关闭算法。
-
接收方
接收方没有办法来处理粘包现象,只能将问题交给应用层来处理。
-
应用层
解决办法:循环处理,应用程序从接收缓存中读取分组时,读完一条数据,就应该循环读取下一条数据,直到所有数据都被处理完成
但是如何判断每条数据的长度呢?
格式化数据:每条数据有固定的格式(开始符,结束符),这种方法简单易行,但是选择开始符和结束符时一定要确保每条数据的内部不包含开始符和结束符。
发送长度:发送每条数据时,将数据的长度一并发送,例如规定数据的前4位是数据的长度,应用层在处理时可以根据长度来判断每个分组的开始和结束位置
4. UDP没有粘包
TCP为了保证可靠传输并减少额外的开销(每次发包都要验证),采用了基于流的传输,基于流的传输不认为消息是一条一条的,是无保护消息边界的(保护消息边界:指传输协议把数据当做一条独立的消息在网上传输,接收端一次只能接受一条独立的消息)。
UDP则是面向消息传输的,是有保护消息边界的,接收方一次只接受一条独立的信息,所以不存在粘包问题。