首页 > 其他分享 >TCP粘包问题如何解决?

TCP粘包问题如何解决?

时间:2023-06-08 15:15:15浏览次数:35  
标签:TCP 粘包 发送 消息 解决 长度 接收

        在TCP的socket编程中,发送端和接收端都有成对的socket。发送端为了将多个发往接收端的包,更加高效的的发给接收端,于是采用了优化算法(Nagle算法),将多次间隔较小、数据量较小的数据,合并成一个数据量大的数据块,然后进行封包。那么这样一来,接收端就必须使用高效科学的拆包机制来分辨这些数据。         TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包,从接收缓冲区来看,后一包数据的头紧接着前一包数据的尾,出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方。   (1) 发送方原因

TCP默认使用Nagle算法(主要作用:减少网络中报文段的数量), 而Nagle算法主要做两件事:
只有上一个分组得到确认,才会发送下一个分组
收集多个小分组,在一个确认到来时一起发送
Nagle算法造成了发送方可能会出现粘包问题

(2) 接收方原因

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

 

TCP产生拆包和粘包的原因:

1、TCP 是基于字节流的,虽然应用层和 TCP 传输层之间的数据交互是大小不等的数据块,但是 TCP 把这些数据块仅仅看成一连串无结构的字节流,没有边界;

2、从 TCP 的帧结构也可以看出,在 TCP 的首部没有表示数据长度的字段。

下面是几种解决TCP粘包问题的方法:

1、使用消息定界符:在每个消息的结尾添加一个特定的字符或者字符序列作为消息的定界符。接收方可以根据定界符判断消息的结束位置,从而正确地解析消息。
2、使用消息长度:在每个消息的开头添加一个指定长度的字段,用于表示消息的总长度。接收方首先读取该字段,然后根据长度读取对应的消息,从而正确地解析消息。
3、使用固定长度的消息:如果每个消息的长度都是固定的,那么接收方可以按照固定长度读取数据,从而正确地解析消息。
4、使用分隔符:可以在每个消息之间添加一个分隔符,例如换行符、制表符等。接收方可以根据分隔符判断消息的结束位置,从而正确地解析消息。
5、应用层协议设计:在设计应用层协议时,可以将每个消息分为消息头和消息体两部分。消息头中包含消息的长度等信息,接收方首先读取消息头,然后根据消息长度读取消息体,从而正确地解析消息。
6、使用TCP_NODELAY选项:将TCP_NODELAY选项设置为1,可以禁用Nagle算法,从而避免数据包在发送缓冲区中积累过多,减少粘包的发生。

 

标签:TCP,粘包,发送,消息,解决,长度,接收
From: https://www.cnblogs.com/lyfily-p-7439305/p/17466539.html

相关文章

  • 【解决方案】DMS驾驶员监测系统自动化测试方案
    什么是DMS?DMS是英文DriverMonitorSystem的缩写,即驾驶员监控系统。主要是实现对驾驶员的身份识别、驾驶员疲劳驾驶以及危险行为的检测功能。目前主流监测方式以通过摄像头等图像传感器获取驾驶员面部图像为基础,运用机器视觉中人脸检测、面部特征点定位等算法技术,对......
  • Android问题解决:android.util.Base64.encode 导致签名不匹配 SignatureDoesNotMatch
    文章目录前文:遇到问题一问:为什么SignatureDoesNotMatch二问:为什么SignatureDoesNotMatch三问:Signature请求参数为什么多了%0A四问:Signature为什么多了换行五问:android.util.Base64.encode的用法前文:遇到问题在折腾《ESP32-C3入门教程——导读》时,需要对接阿里云物联网平台。想要......
  • 【已解决】可视化图表x轴刻度乱序错误
    可视化图表x轴刻度乱序错误bug复现:可以看到下面是乱序的,第一次出现这种情况。于是我试图就是给销量排序。发现还是不行!!这个时候打印一下销量列看一看。可以看到控制台说我们的数据类型是object,是对象,不是int所以这个时候转换一下数据类型。这个时候就正常啦!看看控......
  • win10配置Electron安装环境以及解决报错
    学习electron做桌面应用程序开发,从安装到HellowWorld,过程中遇到的问题以及解决方式。开始学习这边Electron官方文档有详细的步骤。基本要求检查Node.js是否正确安装,请在您的终端输入以下命令:node-vnpm-v创建程序Electron应用程序遵循与其他Node.js项目相同的结构......
  • 解决电脑无法远程Ubuntu,不出界面
    我用的win11远程乌班图22.0参考:https://service.oray.com/question/11969.html......
  • 如何设置Windows操作系统TIME_WAIT状态的TCP连接快速回收时间?
    大规模Windows环境下,采用Nginx反向代理服务后,操作系统会产生较多TIME_WAIT的TCP(TransmissionControlProtocol)连接,操作系统默认TIME_WAIT的TCP连接回收时间是4分钟,TCP默认动态端口范围为开始端口49152,结束端口65535。这样会使回收TCP过慢导致系统吞吐量下降,甚至出现502访问失败问......
  • 解决Vue项目在刷新页面时出现404错误的问题
    使用HTML5的history模式的问题在本地运行Vue项目时,可以直接点击路由跳转,并且刷新页面也没有问题。这是因为VueRouter默认使用HTML5的history模式,它通过修改浏览器历史记录来控制页面跳转,而不发送实际的HTTP请求。然而,当将Vue项目发布到服务器上时,服务器会根据实际的HTTP请求来......
  • win11邮件客户端添加账户时提示「0x80190001」的替代解决方案
    在「添加账户」时选择「高级设置」:高级设置→Internet电子邮件填写信息账户名和用户名可填写邮箱名。如果是微软的邮箱,可参考:传入邮件服务器:POP3.live.com传出邮件服务器:smtp.live.com账户类型可尝试选:POP3......
  • 【解决问题】libevent 编译时报错 Makefile:1708: test/.deps/test_regress-tinytest.
    1开发环境linux版本:统信UOS1030(可以认为是特殊的ubuntu)开发语言:C++2报错现象截图:报错语句:make:进入目录“/home/depend/libevent-2.1.11-stable”Makefile:1708:test/.deps/test_regress-tinytest.Po:没有那个文件或目录make:***没有规则可制作目标“te......
  • 查看tcp和udp端口是否开启
    telnet只能看tcproot@performance:~#telnet192.168.80.1049108Trying192.168.80.104...Connectedto192.168.80.104.Escapecharacteris'^]'.nc既可以看tcp也可以看udptcproot@performance:~#nc-vz192.168.80.1049108192.168.80.104:inversehostlookup......