TCP粘包,拆包及解决方法

TCP粘包和拆包是传输层可能出现的现象,导致接收端难以处理数据。UDP则不会出现此类问题,因为它基于报文发送。粘包、拆包的原因包括数据大小与缓冲区剩余空间、MSS限制、数据量小于缓冲区大小等。解决办法通常是在数据包首部添加长度信息或设定固定长度的数据包。固定长度简单但效率较低,添加长度首部则更高效但实现复杂。

什么是粘包、拆包

  假设客户端向服务端连续发送了两个数据包,用packet1和packet2来表示,那么服务端收到的数据可以分为如下三种:

  1. 第一种情况,接收端正常收到两个数据包,即没有发生拆包和粘包的现象
  2. 第二种情况,接收端只收到一个数据包,由于TCP是不会出现丢包的,所以这一个数据包中包含了发送端发送的两个数据包的信息,这种现象即为粘包。这种情况由于接收端不知道这两个数据包的界限,所以对于接收端来说很难处理
  3. 第三种情况,这种情况服务端一共收到了两个数据包,第一个数据包只包含了第一条消息的一部分,第一条消息的后半部分和第二条消息都在第二个数据包中,或者是第一个数据包包含了第一条消息的完整信息和第二条消息的一部分信息,第二个数据包包含了第二条消息的剩下部分,这种情况其实是发生了TCP拆包,因为发生了一条消息被拆分在两个包里面发送了,同样上面的服务器逻辑对于这种情况是不好处理的

UDP会发生粘包和拆包么?

  如果客户端连续不断的向服务端发送数据包时,服务端接收的数据会出现两个数据包粘在一起的情况,即TCP协议中经常会遇到的粘包以及拆包的问题。
  TCP属于传输层的协议,传输层除了有TCP协议外还有UDP协议,但是UDP不会发生粘包或拆包的现象,因为UDP是基于报文发送的,从UDP的帧结构可以看出,在UDP首部采用了16bit来指示UDP数据报文的长度,因此在应用层能很好的将不同的数据报文区分开,从而避免粘包和拆包的问题。而TCP是基于字节流的,虽然应用层和TCP传输层之间的数据交互是大小不等的数据块,但是TCP把这些数据块仅仅看成一连串无结构的字节流,没有边界;另外从TCP的帧结构也可以看出,在TCP的首部没有表示数据长度的字段,基于上面两点,在使用TCP传输数据时,才有粘包或者拆包现象发生的可能。

粘包、拆包发生原因

发生TCP粘包或拆包有很多原因,现列出常见的几点:
1、要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包
2、待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包
3、要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包
4、接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包

粘包、拆包解决办法

解决问题的关键在于如何给每个数据包添加边界信息,常用的方法有如下几个:
1、发送端给每个数据包添加包首部,首部中应该至少包含数据包的长度,这样接收端在接收到数据后,通过读取包首部的长度字段,便知道每一个数据包的实际长度了
2、发送端将每个数据包封装为固定长度(不够的可以通过补0填充),这样接收端每次从接收缓冲区中读取固定长度的数据就自然而然的把每个数据包拆分开来
3、可以在数据包之间设置边界,如添加特殊符号,这样,接收端通过这个边界就可以将不同的数据包拆分开

  使用两种方法来解决粘包和拆包问题,固定数据包长度和添加长度首部,这两种方法各有优劣。固定数据包长度传输效率一般,尤其是在要发送的数据长度长短差别很大的时候效率会比较低,但是编程实现比较简单;添加长度首部虽然可以获得较高的传输效率,冗余信息少且固定,但是编程实现较为复杂。

固定数据包长度
  这种处理方式的思路很简单,发送端在发送实际数据前先把数据封装为固定长度,然后在发送出去,接收端接收到数据后按照这个固定长度进行拆分即可。

添加长度首部
  这种方式的处理较上面提到的方式稍微复杂一点。在发送端需要给待发送的数据添加固定的首部,然后再发送出去,然后在接收端需要根据这个首部的长度信息进行数据包的组合或拆分。发送端在发送数据前首先给待发送数据添加了代表长度的首部,首部长为4bytes(即int型长度),这样接收端在收到这个数据之后,首先需要读取首部,拿到实际数据长度,然后再继续读取实际长度的数据,即实现了组包和拆包的操作。可以很明显的感觉到这种方法的处理难度相对于固定长度要大一些,不过这种方式可以获取更大的传输效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值