TCP粘包和拆包

TCP粘包和拆包Socket 为 TCP 长连接 TCP 为了保证可靠传输并减少额外的开销 每次发包都要验证 采用了基于流的传输 基于流的传输不认为消息是一条一条的 是无保护消息边界的 保护消息边界 指传输协议把数据当做一条独立的消息在网上传输 接收端一次只能接受一条独立的消息 会存在粘包拆包问题 UDP 则是面向消息传输的 是有保护消息边界的 接收方一次只接受一条独立的信息 所以不存在粘包拆包问题 TCP 是个流协议 就是没有界限的一串数据 TCP 底层并不了解上层业务数据的具体含义 它会根据 TCP 缓冲区的实际情况进行包的划分 所

1、TCP和UDP

Socket为TCP长连接,TCP为了保证可靠传输并减少额外的开销(每次发包都要验证),采用了基于流的传输,基于流的传输不认为消息是一条一条的,是无保护消息边界的(保护消息边界:指传输协议把数据当做一条独立的消息在网上传输,接收端一次只能接受一条独立的消息)。会存在粘包拆包问题。

UDP则是面向消息传输的,是有保护消息边界的,接收方一次只接受一条独立的信息,所以不存在粘包拆包问题。

2、粘包拆包

TCP是个流协议,就是没有界限的一串数据。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为一个完整的包可能会被TCP拆分为多个包进行发送,这就是拆包;也有可能把多个小的包封装成一个大的数据包发送,这就是粘包。

3、粘包和拆包的几种情况

1.第一种情况,Data1和Data2都分开发送到了Server端,没有产生粘包和拆包的情况。

2.第二种情况,Data1和Data2数据粘在了一起,打成了一个大的包发送到Server端,这个情况就是粘包。

3.第三种情况,Data2被分离成Data2_1和Data2_2, 并且Data2_1在Data1之前到达了服务端,这种情况就产生了拆包。

由于网络的复杂性,可能数据会被分离成N多个复杂的拆包/粘包的情况,所以在做TCP服务器的时候就需要首先解决拆包/粘包的问题。

4、出现粘包的原因
出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方。

发送方原因

Negale 算法是指发送方发送的数据不会立即发出,而是先放在缓冲区, 等缓存区满了再发出。发送完一批数据后, 会等待接收方对这批数据的回应,然后再发送下一批数据。Negale 算法适用于发送方需要发送大批量数据, 并且接收方会及时作出回应的场合, 这种算法通过减少传输数据的次数来提高通信效率.

接收方原因

TCP接收到数据包时,并不会马上交到应用层进行处理,或者说应用层并不会立即处理。实际上,TCP将接收到的数据包保存在接收缓存里,然后应用程序主动从缓存读取收到的分组。这样一来,如果TCP接收数据包到缓存的速度大于应用程序从缓存中读取数据包的速度,多个包就会被缓存,应用程序就有可能读取到多个首尾相接粘到一起的包。

5、粘包的处理
– 什么时候需要处理
如果发送方发送的多组数据本来就是同一块数据的不同部分,比如说一个文件被分成多个部分发送,这时当然不需要处理粘包现象
如果多个分组毫不相干,甚至是并列关系,这个时候就一定要处理粘包现象了。

对于发送方造成的粘包问题,可以通过关闭Nagle算法来解决,使用TCP_NODELAY选项来关闭算法。

接收方

接收方没有办法来处理粘包现象,只能将问题交给应用层来处理。

应用层

解决办法:循环处理,应用程序从接收缓存中读取分组时,读完一条数据,就应该循环读取下一条数据,直到所有数据都被处理完成

6、TCP粘包和拆包的解决策略

1.消息定长。例如100字节。不够用0补充。

2.在包尾部增加回车或者空格符等特殊字符进行分割,典型的如FTP协议。

3.将消息分为消息头和消息尾。

4.其他复杂的协议,如RTMP协议等。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/225511.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 上午9:09
下一篇 2026年3月17日 上午9:10


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号