TCP粘包和拆包发生原因和情况分析以及解决方案

目录

TCP粘包的发生原因

TCP粘包拆包的情况分析

粘包和拆包的解决方案 


TCP粘包的发生原因

TCP是一个流式协议,它在传输的过程中是以数据流的形式进行传输的,所谓流,就是没有界限的一串数据。就像河流一样,是练成一片的,数据与数据之间没有完整的界限,TCP底层并不了解上层业务数据的具体的含义,他会根据TCP缓冲区的实际情况进行包的划分,所以在业务认为,一个完整的包可能会被TCP拆成多个包进行发送,也有可能会把多个小的数据包封装成一个大的数据,这就是所谓的TCP粘包和拆包的发生原因

TCP粘包拆包的情况分析

假设客户端分别发送了两个数据包A1和A2给服务端,由于服务器端一次读取到的字节数是不确定的故可能会存在以下的四种情况。

1.服务器端接到了两个独立的数据包A1和A2,没有发生粘包和拆包的情况

2.服务器端同时接到了A1和A2这两个完整的数据包,A1和A2粘和在一起,被称之为TCP粘包

 

3.服务器分两次读取到了两个数据包,第一次读到了A1的部分数据包,第二次读取到了A1剩下的数据包和完整的A2完整数据包,被称之为TCP拆包,就是将A1这个完整的数据包拆成两个甚至是多个数据包进行发送

4.服务器分两次读取到了两个数据包,第一次读到了A1的完整数据包和A2的部分数据包,第二次读取到了A2剩下的数据包,也被称之为TCP拆包,就是将A2这个完整的数据包拆成两个甚至是多个数据包进行发送

如果此时服务器的TCP的滑动窗口非常小,而数据包A1和A2比较大,很可能会发生第五种情况,即服务器分多次才能将A1和A2包发送完全,期间发生多次拆包

粘包和拆包的解决方案 

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

  1. 客户端在发送数据包的时候,每个包都固定长度,比如1024个字节大小,如果客户端发送的数据长度不足1024个字节,则通过补充空格的方式补全到指定长度;
  2. 客户端在每个包的末尾使用固定的分隔符,例如\r\n,如果一个包被拆分了,则等待下一个包发送过来之后找到其中的\r\n,然后对其拆分后的头部部分与前一个包的剩余部分进行合并,这样就得到了一个完整的包;
  3. 将消息分为头部和消息体,在头部中保存有当前整个消息的长度,只有在读取到足够长度的消息之后才算是读到了一个完整的消息;
  4. 通过自定义协议进行粘包和拆包的处理。

猜你喜欢

转载自blog.csdn.net/asdasd121312dasd/article/details/127974960
今日推荐