1

背景:我花了一段时间使用各种设备接口,并且看到了很多协议,很多串行和 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,直到您用足够的字节填充输入缓冲区以满足损坏的长度场的要求。

那么有没有一种确定的方法来解决这个问题,无论是在接收处理程序中还是在协议设计本身中?我可以设置最大数据包长度或超时来刷新接收处理程序中的接收缓冲区,这应该在实际层面上解决问题,但我仍然想知道是否有适用于一般情况的“纯”理论解决方案并且不需要设置特定于实现的最大长度或超时。

谢谢!

4

2 回答 2

3

我所知道的所有协议,包括那些处理“流”数据的协议,都将数据流分割成较小的传输单元,每个传输单元都有自己的检查,这正是为了避免您描述的问题。您的协议设计中的根本缺陷可能是块太大。

这个 SO question的公认答案包含一个很好的解释和一个关于这个主题的非常有趣(但数学相当重)的论文的链接。

所以简而言之,您应该坚持使用较小的传输单元,不仅因为与实际编程相关的参数,而且因为消息长度在确定您的 crc 提供的安全性方面的作用。

于 2012-06-29T15:57:17.673 回答
1

一种方法是对长度参数进行编码,以便很容易检测到它已损坏,并避免读取大缓冲区以检查 CRC。

例如,XModem 协议嵌入了一个 8 位的数据包编号,后跟它的补码。

这可能意味着将您的长度块大小加倍,但这是一种选择。

于 2012-06-30T20:09:08.437 回答