TCP粘包、半包
原因
粘包和半包现象在TCP连接数据传输过程中经常出现,半包、粘包现象是指数据在传输过程中接受端出现数据不完整或者数据包粘连等情况,造成这种现象的根本原因与TCP协议的数据传输方式和底层操作系统有关,主要原因可归纳为以下两方面:
- 基于TCP的数据传输是面向流传输,接收端接收的数据包没有明确的头尾标志
- 为了提高效率,数据不是立即传输,而是写入缓冲区分批传输,数据较小的包会进行合并操作(Nagle算法),接收端因此会出现粘包现象
TCP数据传输过程接受端接收数据包情形可分为以下3种:
数据包正常发送
正常发送情况服务端会依次接收到两个数据包,不存在粘包和半包的现象
粘包
客户端依次发出Packet1和Packet2,但是由于两个包较小,在缓冲过程中进行可合并操作,当服务端接收到数据包时,实际数据包是Packet1+pakcet2,出现粘包现象,客户端发送了两个包,服务端只接收到一个。
半包、粘包
传输数据存在半包和粘包情况,这种情形分为两种表现形式,客户端依次发出Packet
1和Packet2两个数据包,但是两个数据包存在半包、粘包现象
常见解决方案
对于TCP协议数据传输中半包、粘包等问题,不可避免,但是在实际应用中有常用的解决方案可以完全避免这种情况的发生,主要以下几个方法规避半包、粘包等问题:
- 使用定长数据包,服务端和客户端约定数据包的长度,服务端每次读取定长数据,如果数据包长度小于约定数据包长度则认为消息不完整,可直接忽略
- 使用固定分隔符作为包结束标志,服务端在接收数据包时按照约定的结束标志还读取数据
- 结构化数据包格式,可分为消息头和消息体的格式,消息头长度为固定长度,消息头中应至少包含消息体长度,也可包含消息格式等附件信息,避免粘包、半包现象。