求tcp接受数据,快速匹配数据包头部的方法

shanyang1 2013-05-06 02:40:05
某数据流,头部特征为0x00 0x40 0x01 0x00 0x01 0x31 0x9f 0x00 0x00 0x30 0x30 0x30 0x30 0x2e 0x30 0x30 0x30这17个字节,字节中的16进制代码完全可能在数据流中出现,因此匹配必须连续16个字节完全符合头部特征定义才行,头部的16个字节后,跟着10240个实际数据,在每个头部和上一个数据间,可能存在随机填充的长度不定的字节

客户端数据的接受在while(true)循环中进行,每次接受的字节数可以自定

因为数据流量很大,计算要精简,最好避免使用for循环进行匹配
有什么合适的算法么能找到头部么

...全文
825 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
showjim 2013-05-07
  • 打赏
  • 举报
回复
引用 8 楼 sp1234 的回复:
但是如果是长连接的,并且同一个客户端也可以并发地发送多个(例如几百个)消息并且以随即顺序收到对方发来的结果,那么很自然地就存在大量沾包解析问题。
发送方竟然没有会话概念,沾包解析 那是自找的。
  • 打赏
  • 举报
回复
引用 4 楼 tcmakebest 的回复:
真的挺费的,还不如一次连接就发一个数据包算了,都不用头部,发完就断线。 或者用XML把数据包装一下,解析方便极了。 否则只能使用 for 了。
背景知识完全不同。 如果是短链接tcp通讯,或者就是普通的udp通讯,那么就是一问一答形式,根本用不着什么分隔符。 但是如果是长连接的,并且同一个客户端也可以并发地发送多个(例如几百个)消息并且以随即顺序收到对方发来的结果,那么很自然地就存在大量沾包解析问题。
  • 打赏
  • 举报
回复
关于这个查询,虽然有着所谓的“快速匹配”算法,但是其实测试下来也没有多大必要采用。就是普通的按字节for循环比较就行。
  • 打赏
  • 举报
回复
引用 楼主 shanyang1 的回复:
某数据流,头部特征为0x00 0x40 0x01 0x00 0x01 0x31 0x9f 0x00 0x00 0x30 0x30 0x30 0x30 0x2e 0x30 0x30 0x30这17个字节,字节中的16进制代码完全可能在数据流中出现,因此匹配必须连续16个字节完全符合头部特征定义才行,头部的16个字节后,跟着10240个实际数据,在每个头部和上一个数据间,可能存在随机填充的长度不定的字节 客户端数据的接受在while(true)循环中进行,每次接受的字节数可以自定 因为数据流量很大,计算要精简,最好避免使用for循环进行匹配 有什么合适的算法么能找到头部么
在我们的服务器中,每一次启动都会随机产生不同的分隔符。例如
public static string SeparatedText = "**%&#@!*" + Guid.NewGuid().ToString("n");   //消息分隔符
客户端第一次连上服务器之前,先要使用
new WebClient().DownloadData(...)下载次分隔符,然后才能使用tcp连。
showjim 2013-05-06
  • 打赏
  • 举报
回复
这个数据用KMP效率有点低,扫描某个特征字节(比如0x40)就可以了,这样的O(n)更高效。
tcmakebest 2013-05-06
  • 打赏
  • 举报
回复
真的挺费的,还不如一次连接就发一个数据包算了,都不用头部,发完就断线。 或者用XML把数据包装一下,解析方便极了。 否则只能使用 for 了。
gomoku 2013-05-06
  • 打赏
  • 举报
回复
引用 楼主 shanyang1 的回复:
...每个头部和上一个数据间,可能存在随机填充的长度不定的字节...
另外,这不是好的通信协议。
gomoku 2013-05-06
  • 打赏
  • 举报
回复
KMP 详见:http://zh.wikipedia.org/wiki/克努斯-莫里斯-普拉特算法
jy251 2013-05-06
  • 打赏
  • 举报
回复
linq+正则表达式

111,092

社区成员

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

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

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