TCP粘包/拆包

目录

粘包

粘包出现原因

为了避免粘包现象,可采取以下几种措施

消息保护边界


参考:

https://www.cnblogs.com/kex1n/p/6502002.html

粘包

发送方发送的若干数据包到接收方接收时粘成一个包,从接收缓冲区看,后一包数据的头紧接着前一包的数据的尾。粘包的原因有可能是发送方也有可能是接收方导致的。

粘包出现原因

简单得说,在流传输中出现,UDP不会出现粘包,因为它有消息边界(参考Windows网络编程)

1发送端需要等缓冲区满才发送出去,造成粘包

2接收方不及时接收缓冲区的包,造成多个包接收

具体点:

(1)发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常TCP会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。

(2)接收方引起的粘包是由于接收方用户进程不及时接收数据,从而导致粘包现象。这是因为接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据尚未被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据之后,而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据。

粘包情况有两种,一种是粘在一起的包都是完整的数据包,另一种情况是粘在一起的包有不完整的包。

不是所有的粘包现象都需要处理,若传输的数据为不带结构的连续流数据(如文件传输),则不必把粘连的包分开(简称分包)。但在实际工程应用中,传输的数据一般为带结构的数据,这时就需要做分包处理。

在处理定长结构数据的粘包问题时,分包算法比较简单;在处理不定长结构数据的粘包问题时,分包算法就比较复杂。特别是粘在一起的包有不完整的包的粘包情况,由于一包数据内容被分在了两个连续的接收包中,处理起来难度较大。实际工程应用中应尽量避免出现粘包现象。

 

为了避免粘包现象,可采取以下几种措施

(1)对于发送方引起的粘包现象,用户可通过编程设置来避免,TCP提供了强制数据立即传送的操作指令push,TCP软件收到该操作指令后,就立即将本段数据发送出去,而不必等待发送缓冲区满;

(2)对于接收方引起的粘包,则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施,使其及时接收数据,从而尽量避免出现粘包现象;

(3)由接收方控制,将一包数据按结构字段,人为控制分多次接收,然后合并,通过这种手段来避免粘包。

以上提到的三种措施,都有其不足之处。

(1)第一种编程设置方法虽然可以避免发送方引起的粘包,但它关闭了优化算法,降低了网络发送效率,影响应用程序的性能,一般不建议使用。

(2)第二种方法只能减少出现粘包的可能性,但并不能完全避免粘包,当发送频率较高时,或由于网络突发可能使某个时间段数据包到达接收方较快,接收方还是有可能来不及接收,从而导致粘包。

(3)第三种方法虽然避免了粘包,但应用程序的效率较低,对实时应用的场合不适合。

 

一种比较周全的对策是:接收方创建一预处理线程,对接收到的数据包进行预处理,将粘连的包分开。对这种方法我们进行了实验,证明是高效可行的。

 

TCP是面向连接的,TCP的socket编程,收发两端(客户端和服务端)都要有成对的socket,因此,发送端为了将多个发往接收端的包更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小、数据量小的数据,合并成一个大的数据块,然后进行封包。这样,接收端就很难分辨,必须提供科学的拆包机制。

对于数据传输频繁的程序来说,使用TCP可能会容易粘包。对于接收端程序来说,如果机器负荷很重,也会在接收缓冲里粘包。这样就需要接收端额外拆包,增加了工作量。

消息保护边界

传输协议把数据当作一条独立的消息在网上传输,接收端只能接收独立的消息。即如果存在消息保护边界,接收端一次只能接收发送端发送的一个数据包。

TCP基于流式传输,没有消息保护边界。它把数据当作一串数据流,如果发送端连续发送数据,接收端有可能再一次接收动作中,会接收两个或者更多的数据包。

如果连续发送3个数据包,大小分别是2k,4k,8k。如果使用UDP协议,不管用多大的接收缓冲区去接收数据,都必须有三次接收动作,才能够把数据报接收完。而使用TCP协议,只需要把接收端缓冲区大小设置在14k以上,就能一次把所有的数据包接收下来,只需要一次接收动作。

send(data, length)与recv(buff)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值