转载自 https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247484306&idx=1&sn=a305e8e7da212c44c233a04ec328cdd2&chksm=ebd74293dca0cb856896abe4d729c15dc4c328699c543b7a60b8650d7c3ed52a418d7103ab13&scene=21###wechat_redirect


3.1什么是拆包粘包?为什么会出现?

在进行Java NIO学习时,可能会发现:如果客户端连续不断的向服务端发送数据包时,服务端接收的数据会出现两个数据包粘在一起的情况。

TCP的首部格式:

  • TCP是基于字节流的,虽然应用层和TCP传输层之间的数据交互是大小不等的数据块,但是TCP把这些数据块仅仅看成一连串无结构的字节流,没有边界

  • 从TCP的帧结构也可以看出,在TCP的首部没有表示数据长度的字段

基于上面两点,在使用TCP传输数据时,才有粘包或者拆包现象发生的可能。

一个数据包中包含了发送端发送的两个数据包的信息,这种现象即为粘包

接收端收到了两个数据包,但是这两个数据包要么是不完整的,要么就是多出来一块,这种情况即发生了拆包和粘包

拆包和粘包的问题导致接收端在处理的时候会非常困难(因为无法区分一个完整的数据包)

3.2解决拆包和粘包

分包机制一般有两个通用的解决方法:

  • 1,特殊字符控制

  • 2,在包头首都添加数据包的长度

如果使用netty的话,就有专门的编码器和解码器解决拆包和粘包问题了。

tips:UDP没有粘包问题,但是有丢包和乱序。不完整的包是不会有的,收到的都是完全正确的包。传送的数据单位协议是UDP报文或用户数据报,发送的时候既不合并,也不拆分。