锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / C++行业技术开源 / 通信粘包、串口粘包、SOCKET粘包、TCP粘包
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

通信粘包、串口粘包、SOCKET粘包、TCP粘包


通信粘包是指接收时收到了发送端多次混合起来的数据包,理想状态是一发一收,发送端和接收端都好处理,但是实际上理想状态总是有偏差的。在大并发操作系统通信负荷大、模拟环境虚拟机性能差、进程线程多进程通信负荷大和网络节点通信压力大,偏差波动越来越大,就会产生粘包。


串口粘包

串口通信开发比SOCKET套接字简单,但是里面也有时序参数配置,配置不好通信也容易异常。在使用虚拟串口软件或虚拟机VMWare操作系统通信时,有偏差极端情况 下会有串口粘包。在串口开发时,特别相信会是一发一收理想状态,但是我就在偏差极端情况下遇到过串口粘包。一组一组数据取出来,发现不适合用,加上包头包尾标志判断才算处理好。


SOCKET粘包和TCP粘包

SOCKET粘包和TCP粘包经常放到一起来讲,因为TCP的缓冲机制,容易让小包聚集在接收端,或者大包上个的后半部分和下包的上半部分聚集在一起,网上的文章说解决办法有:短连接、固定长度、分隔符和专门的Length字段,其实这些处理不办法不全面,最好是长度和包标志都带上,类似TCP底层的包结构。另外在具体编程时,注意用强制刷新缓冲区让操作系统不等待,立即发送来进行控制。

锐英源软件从事过OpenSSL通信开发,用到过刷新缓冲区,代码如下:

			iwrite = SSL_write(ssl, psend, ilen);
			BIO_flush(sbio);
			if (iwrite <= 0)
			{
				strcpy(szErrMsg, "发送命令失败");
				LOG_ERROR << cUser << "配置中断----发送命令失败";
				//LogSSLError(("写"));
				bCommError = true;
				return iwrite;
			}

BIO_flush就是强制刷新缓冲区函数。

把长度和包标志都带上后,接收端接收时按流式缓冲处理,先接收长度,再按长度接收数据,判断尾部正确与否,不正确抛弃,同时回复给发送端错误信息;正确就处理,并从头删掉开头长度的缓冲数据。

C++一般用原生函数send和recv处理,不太好实现流式缓冲处理,不过网上有源代码封装的不错,大家可以找找。C#的NetworkStream和MemoryStream类似类比较多,处理方便。如果初学者不太好用C++掌握,用C#开发相应的处理代码,容易掌握流的原理。锐英源软件用C#开发过教育平台,平台里有组播和点对点通信,通信状态很复杂,但是用好了C#流处理,处理好了SOCKET粘包和TCP粘包问题。

如果大家想证实粘包情况,可以用wireshark抓包,如果操作系统卡,觉得wireshark不方便打开,用tshark来抓包也行,在卡的时候,迟迟收不到发送端的数据包,在突然收到时就会是粘包情况。

粘包不复杂,但是最好不要让出现粘包,开始就设计好服务器端和客户端架构,保证通信吞吐能力,不让数据处理出现波动,才是更好的解决方案。

友情链接
版权所有 Copyright(c)2004-2024 锐英源软件
统一社会信用代码:91410105098562502G 豫ICP备08007559号 最佳分辨率 1440*900
地址:郑州市金水区文化路97号郑州大学北区院内南门附近