TCP粘包和拆包问题

Posted -mrl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP粘包和拆包问题相关的知识,希望对你有一定的参考价值。

1)产生TCP粘包和拆包问题的主要原因是,操作系统在发送TCP数据的时候,底层会有一个缓冲区,例如1024个字节大小,如果一次请求发送的数据量比较小,没达到缓冲区大小,TCP则会将多个请求合并为同一个请求进行发送,这就形成了粘包问题;如果一次请求发送的数据量比较大,超过了缓冲区大小,TCP就会将其拆分为多次发送,这就是拆包,也就是将一个大的包拆分为多个小包进行发送。TCP属于传输层的协议,传输层除了有TCP协议外还有UDP协议。那么UDP是否会发生粘包或拆包的现象呢?答案是不会。UDP是基于报文发送的,从UDP的帧结构可以看出,在UDP首部采用了16bit来指示UDP数据报文的长度,因此在应用层能很好的将不同的数据报文区分开,从而避免粘包和拆包的问题。而TCP是基于字节流的,虽然应用层和TCP传输层之间的数据交互是大小不等的数据块,但是TCP把这些数据块仅仅看成一连串无结构的字节流,没有边界;另外从TCP的帧结构也可以看出,在TCP的首部没有表示数据长度的字段,基于上面两点,在使用TCP传输数据时,才有粘包或者拆包现象发生的可能。如下图展示了TCP粘包和拆包的一个示意图:

 技术图片

 

 

上图中演示了TCP粘包和拆包的三种情况:

·A和B两个包都刚好满足TCP缓冲区的大小,或者说其等待时间已经达到TCP等待时长,从而还是使用两个独立的包进行发送;

·A和B两次请求间隔时间内较短,并且数据包较小,因而合并为同一个包发送给服务端;

·B包比较大,因而将其拆分为两个包B_1和B_2进行发送,而这里由于拆分后的B_2比较小,其又与A包合并在一起发送。

 

2)对于粘包和拆包问题,常见的解决方案有四种:

·客户端在发送数据包的时候,每个包都固定长度,比如1024个字节大小,如果客户端发送的数据长度不足1024个字节,则通过补充空格的方式补全到指定长度;

·客户端在每个包的末尾使用固定的分隔符,例如 ,如果一个包被拆分了,则等待下一个包发送过来之后找到其中的 ,然后对其拆分后的头部部分与前一个包的剩余部分进行合并,这样就得到了一个完整的包;

·将消息分为头部和消息体,在头部中保存有当前整个消息的长度,只有在读取到足够长度的消息之后才算是读到了一个完整的消息;

·通过自定义协议进行粘包和拆包的处理。

以上是关于TCP粘包和拆包问题的主要内容,如果未能解决你的问题,请参考以下文章

TCP粘包和拆包

TCP 粘包和拆包及解决方案

TCP粘包和拆包问题

解决粘包和拆包问题

计网 - TCP 的封包格式:TCP 为什么要粘包和拆包?

粘包和拆包