背景:我花了一些时间处理各种设备接口,并且看到了许多协议,许多串行和UDP,其中数据完整性在应用程序协议级别处理。我一直在寻求改进我接收的常规协议处理,并考虑协议的“理想”设计。
我的问题是:是否有任何协议框架方案可以明确识别所有情况下的损坏数据?例如,考虑许多协议的标准成帧方案:
Field: Length in bytes
<SOH>: 1
<other framing information>: arbitrary, but fixed for a given protocol
<length>: 1 or 2
<data payload etc.>: based on length field (above)
<checksum/CRC>: 1 or 2
<ETX>: 1
对于绝大多数情况,这很好。当您收到一些数据时,搜索SOH(或您的起始字节序列是什么),向您的长度字段前进固定数量的字节,然后将该字节数(加上或减去一些固定偏移量)移动到数据包的结尾到你的CRC,如果检查结果你知道你有一个有效的数据包。如果输入缓冲区中没有足够的字节来查找SOH或根据长度字段获得CRC,那么请等到收到足够的CRC来检查CRC。忽略CRC冲突(我们可以做的不多),这可以保证您的数据包格式良好且不会损坏。
但是,如果长度字段本身已损坏且值很高(我正在运行),那么在用足够的字节填满输入缓冲区之前,您无法检查(损坏的)数据包的CRC。腐败长度字段的要求。
那么在接收处理程序或协议设计本身中是否有一种确定性的解决方法?我可以在接收处理程序中设置一个最大数据包长度或超时来刷新我的接收缓冲区,这应该在实际层面上解决问题,但我仍然想知道是否存在适用于一般情况的“纯粹”理论解决方案并且不需要设置特定于实现的最大长度或超时。
谢谢!
答案 0 :(得分:3)
我所知道的所有协议(包括那些处理“流”数据)的原因是,在较小的传输单元中切断数据流,每个都有自己的检查,这正是为了避免您描述的问题。可能你的协议设计的根本缺陷是块太大了。
accepted answer of this SO question包含一个很好的解释和一个关于这个主题的非常有趣(但相当重的数学)论文的链接。
简而言之,您应该坚持使用较小的传输单元,这不仅是因为实际的编程相关参数,还因为消息长度在确定crc提供的安全性方面的作用。
答案 1 :(得分:1)
一种方法是对长度参数进行编码,以便容易检测到它被破坏,并使您无需在大缓冲区中读取以检查CRC。
例如,XModem协议嵌入一个8位数据包编号,然后是一个补码。
这可能意味着你的长度大小加倍,但它是一个选项。