protobuf实现未使用的字节(用于限制器实现)

时间:2018-07-19 07:58:14

标签: protocols protocol-buffers delimiter nanopb

我需要通过串行端口传输数据。为了确保数据的完整性,我希望每个protobuf消息周围都有一个小的信封协议。我考虑了以下问题:

  1. 消息类型(1个字节)
  2. 邮件大小(2个字节)
  3. protobuf消息(N个字节)
  4. (校验和;可选)

消息类型主要是原型文件中定义的消息之间的映射。但是,如果消息损坏或某些字节丢失,则消息大小将不正确,并且所有后续字节也无法再解释。解决此问题的一种方法是在消息之间引入限制器,但是为此,我需要选择protobuf不使用的东西。有没有任何protobuf消息从未使用过的字节序列?

我还考虑了另一种方式。如果主机发现软件包已损坏,则应将通信重置为干净的开始。为此,我希望主机向从机发送一个RESTART命令。从机应以ACK应答,然后再次开始发送完整的消息。主机将丢弃RESTART和ACK之间收到的所有字节。我想将ACK和RESTART编码为特殊消息。但是用这种方法,我面临着同样的问题:我需要找到ACK和RESTART的字节序列,而这些字节序列没有被任何protobuf消息使用。

也许我也采用了错误的方法-随时建议其他方法来处理丢失的字节。

2 个答案:

答案 0 :(得分:1)

  

是否存在任何protobuf消息从未使用过的字节序列?

否;它是一个二进制序列化程序,可以包含任意二进制有效载荷(尤其是bytes类型的二进制有效载荷)。您不能使用前哨值。长度前缀很好(您的“邮件大小”标头),校验和可能是一个实用的选项。或者,您可以施加一个人工哨兵来跟踪每条消息(可能是每个连接选择的GUID作为初始握手的一部分),并使用它来仔细检查所有内容是否正确。

答案 1 :(得分:0)

一种罕见的问题后帮助恢复数据包同步的一种方法是在消息的开头使用同步字,并使用校验和检查有效消息。

这意味着您输入了一个恒定值,例如0x12345678,在您的消息类型字段之前。然后,如果邮件未通过校验和检查,则可以通过在数据中查找下一个0x12345678来恢复。

即使该值有时可能出现在消息中间,也没关系。校验和检查很可能会发现该位置没有真实的消息,您可以向前搜索,直到找到下一个标记。