TCP粘包问题 (TCP Stick Package)

什么是粘包问题:

粘包问题是指TCP客户端接收到的数据中,前一个应用层数据包与后一个应用层数据包在用户缓冲区中是没有分隔的,直接连在一起。需要应用层来识别边界并分隔数据包。

粘包问题出现的原因:

简单得说,在流传输中才会出现粘包问题(如TCP),而使用UDP就不会出现粘包,因为UDP有消息边界。UDP接收端的套接字缓冲区采用了链式结构来记录每一个到达的UDP包,接收端每次recvfrom只能读取一个UDP包,所以不会出现tcp数据流的粘包问题。

对于tcp流:

1. 发送端需要等缓冲区满才发送出去,造成多个应用层数据一起发送,造成粘包;

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

具体点说:

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

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

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

粘包问题处理:

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

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

粘包问题避免:

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

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

但是由于网络线路的MTU限制,路由器也会分包合包,所以我觉得粘包问题是没办法避免的。最终还是需要应用层在接收数据时根据数据的结构实现逻辑进行分包。

发布了87 篇原创文章 · 获赞 64 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/wqfhenanxc/article/details/88064381