串口通信数据包粘在一起的问题

前朝遗民 2018-08-16 06:32:16
用串口通信,收到数据,有时候能分开,像这样:
BB 09 01 02 35 F1 01 54 01 F0 54 17 0B 02 34 01 25 10
BB 08 01 02 00 F1 01 0A 00 10 20 30 40 50 60 57 10
(BB是起始标志,最后的10是结束标志,倒数第二个是校验)

有时候却连在一起,像这样:
BB 09 01 02 35 F1 01 54 01 F0 54 17 0B 02 34 01 25 10 BB 08 01 02 00 F1 01 0A 00 10 20 30 40 50 60 57 10

怎样才能做到不粘连在一起呢?
...全文
1363 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
Maybe_ch 2018-09-04
  • 打赏
  • 举报
回复
自己通过开始结束标志进行分割。之前也才遇到了这个问题。
依然冷暖 2018-08-17
  • 打赏
  • 举报
回复
粘包 正常因该是 主UI处理数据响应时间过长导致的 之前我试过 主UI什么都不做 只是单纯的显示数据 使用invoke的方式 在数据包间隔10Ms发送的情况下 从没出现过粘包
「已注销」 2018-08-17
  • 打赏
  • 举报
回复
Tcp通讯不是面向消息的,这种情况出现是很正常的,所以在设计上应该在接收的位置加一个缓存区的。根据校验规则和结束标志,截取完整的数据包,然后再做进一步处理
  • 打赏
  • 举报
回复
实际上,我们设计通讯协议,都是假设一端可能连续发送 n 多个信令的。比如说一端给另一端发送指令 1、2、3、4、5,而接收端根据自己并发处理的实际情况,可能以顺序 2、1、4、3、5 来返回结果。双方应该可以正确地知道信令的序号,能正确处理。同时流式消息处理应该是通用的,都能处理粘包、分包情况,在信令设计文档中一看就知道有这方面的知识。
  • 打赏
  • 举报
回复
引用 2 楼 okhorse 的回复:
我这个C#程序是从Delphi程序翻译过来的,运行Delphi的程序,还没出现过粘包的问题,仔细核对过程序,没发现有哪里不同,伤脑筋啊


如果你使用极低效率的、按行文本的、阻塞的方式就够了,那么你应该使用 ReadLine 来读取文本。而不是采用事件驱动方式。
晨易夕 2018-08-17
  • 打赏
  • 举报
回复
知道起始标识,自己校验长度拆分或截取就好了。
有些时候对方的设备可能会使用主动发送数据包的方式向你提交数据,你不用事件驱动,主动接收的话有可能读到的是两包,也可能一包半。
xian_wwq 2018-08-17
  • 打赏
  • 举报
回复
数据接收和数据解析最好分离
否则数据解析中出现异常就可能
会导致接收出现异常
xuzuning 2018-08-16
  • 打赏
  • 举报
回复
你的包中内有长度字段,是问题的根本所在
xuzuning 2018-08-16
  • 打赏
  • 举报
回复
你两个包一起发,自然就粘在一起了
采用应答的方式就不会了
sj490790083 2018-08-16
  • 打赏
  • 举报
回复
既然有起始标志和结束标志,自己分割一下不就好了
前朝遗民 2018-08-16
  • 打赏
  • 举报
回复
引用 1 楼 stherix 的回复:
不粘在一起你是控制不了的,这不是udp,还有可能一次只有包的一部分
所以你的代码里要解决粘包和分包的问题
由包头/长度/包尾等手段将字节流里的独立包拆出来并解析


我这个C#程序是从Delphi程序翻译过来的,运行Delphi的程序,还没出现过粘包的问题,仔细核对过程序,没发现有哪里不同,伤脑筋啊
stherix 2018-08-16
  • 打赏
  • 举报
回复
不粘在一起你是控制不了的,这不是udp,还有可能一次只有包的一部分
所以你的代码里要解决粘包和分包的问题
由包头/长度/包尾等手段将字节流里的独立包拆出来并解析
1、本软件可以实现通过网络转换成串口,或者串口转串口,网络转网络形式,将数据的原始包进行转发(数据透明传输)。 2、虚拟串口需要安装串口驱动,目前支持WIN2k、XP及WIN7操作系统。 3、如果是通过网络连接,在网络连接时间内没有数据传送,可以设置系统自动断开的时间长度,默认600s 4、本软件支持花生壳域名解析服务启动、停止,如果需要域名解析请联系我,我将给您提供一个用户名及密码,来完成此项功能。 5、如果是自动打开连接选择了,则系统会在下一秒内自动再次连接;本软件可以设置成随操作系统自动启动。 6、(串口连串口)客户端连接方式选择串口,会出现用户可以创建的虚拟串口(必须先安装串口驱动),连接设置后一个输入框是设定串口数据帧间间隔时间长度,系统默认设置为20ms,如果用户需要快的数据应答可以设置为1ms;用户的软件连接启动一个串口,本软件连接一个串口,比如:选择创建OCM4和COM5 在客户端连接方式选择COM4,用户软件选择COM5,在连接服务器端选择系统存在的一个串口比如COM1,连接到用户的设备或者仪器仪表,通过显示数据就看看到整个数据通信包。 7、(网络连网络)在客户端或服务器端选择连接方式,目前客户端支持TCP/UDP方式,服务器端支持TCP方式,可实现由UDP转为TCP连接方式的数据传输。 8、(网络连串口)与6、7说明一致,只是把网络数据包转换成串口数据包,或串口数据包转换成网络数据包,以上3种方式支持自动连接。 9、网络连接方式设置,连接服务器端设置及状态栏,选择客户端连接方式,可以设置注册包和心跳包,第一个是注册包是网络连接到用户指定的IP地址和端口后,发送的一个数据包,第三个是心跳包,可以设置在连接过程中每(默认60s)发送一个心跳包给对方的连接,一般是针对组态软件设定的,如果是用户自己编程的可以留空,(留空是不进行发送数据) 选择服务器连接方式,可以启动辅助监听方式,如果输入设备名称后,默认客户端连接的第一个数据包为注册包,以后的数据包和心跳包相同的话为心跳包,其余为用户数据包,进行转发,如果未锁定连接,则第二个TCp连接会直接替代第一个TCP连接。 10、在连接方式选择网络时,可以启动服务器监听,并打开端口,如果有外来的连接连接到监听端口,如果外来连接发送过来注册包(连接开始后的第一个数据包),和设置的设备名称一致,则系统自动会把连接设置的对方IP地址修改成这个外来连接的地址,客户端再去主动连接这个IP和端口,这中方式一般针对外来IP地址是动态的并且能主动连接到本系统,如果有连接不清楚可以联系QQ16148947(这种方式用户很少用到) 11、在连接方式选择服务器端是,如果设备名称不输入,这是所有的连接默认接入就直接使用,如果有输入设备名称,则可以过滤连接,并且外来连接连接后,第一个数据包认为为注册包,应该为设备名称对应,否则不进行数据转发,且下一个连接来后直接替换该连接,如果设备名称和客户连接的一个数据相同的话,就进行当前连接,不理会其他的连接,(如果在无数据通信断线的情况下,也会自动断开) 12、如需要连接TDU,则可以选择服务端的服务器方式,并打开辅助监听端口,把端口设置成一致,如果有注册包,则在“设备名称中输入”,如果有心跳包,则在“心跳中”输入,支持英文及数字。 13、支持启动域名服务,远程只需要输入域名及端口就可以进行远程连接到本系统! 14、支持串口数据监控功能,在服务器端,选择相应的串口,在启动监控后对相应的选项进行选择,则可以对串口数据进行监控显示,方便用户分析通信数据包! 15、只要显示两边的状态是在连接中...就能对在线的2个网络连接实现互通数据包; 16、调试状态下网络或串口模式能显示应答的时间长度;能进行Modbus协议的读写操作;字节数据转换为浮点数或双精度数! 17、双击连接设置输入框,能获取本机局域网所在的外网IP地址! 18、双击发送或接收或“清”按钮能清空计数及显示字符. 19、谢谢欢迎提供改进意见;也可以进行有偿软件定制功能,如果您在使用,联系QQ16148947或请加入群:72950899;我们一起探讨升级;请注明远程数据模块连接!

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧