【问题标题】:Wire Protocol Serialization有线协议序列化
【发布时间】:2018-06-12 13:06:02
【问题描述】:

我正在寻找我称之为“二进制序列化器/反序列化器代码生成器”的东西,因为没有更好的术语专门允许您指定 on-the-wire 格式任意位长度,然后生成必要的 C/C++ 代码以该格式打包/解包数据包。我开始使用带有位字段的结构,但在阅读this post 之后,我想知道是否已经有一些东西可以处理所有混乱的问题。我需要处理的示例数据结构:

struct header {
    unsigned int val1 : 8;
    unsigned int val2 : 24;
    unsigned int val3 : 16
    unsigned int val4 : 2;
    unsigned int val5 : 3;
    unsigned int val6 : 1;
    unsigned int val7 : 10;
}

保持这样的数据结构字段的动机是,它使程序员的工作更容易根据它们在协议中匹配的内容来设置/获取字段,例如。 val5 可能是一个有意义的 3 位标志。是的,我可以为整个结构设置两个 32 位值,并且必须使用位掩码和其他东西来跟踪所有内容,但为什么呢?

我知道诸如 Google Proto Buf 之类的东西,但是 AFAIK 这些都专注于程序员端的数据结构,并且不允许您指定特定的位模式 - 想象一下尝试为低级创建客户端代码二进制线格式是如何指定的协议。我发现的最接近的东西是protlr,这听起来不错,但它似乎不是 FOSS。 SO上的其他帖子指向:

  • RedBlocks 似乎是一个成熟的嵌入式框架的一部分。
  • PADS 这对于我的需求来说似乎非常陈旧且过于复杂。
  • binpac 听起来很有趣,但我找不到使用它来解析任意位长度(例如 1 位、2 位、17 位字段)的示例,或者它是否也具有序列化方法,因为它似乎专注于一个入侵检测的反序列化方式。

除了滚动yet another serialization format 之外,是否有符合我标准的 FOSS 替代方案,或者有人可以提供使用上述结构中的这些参考资料之一的示例吗?

【问题讨论】:

  • 位域的排序本质上不是可移植的——任何代码生成器都必须为不同的架构生成单独的代码。
  • OTOH,如果您要生成具有执行正确移位和掩码的内联访问器函数的 C++ 标头,无论如何您都可能会获得位域的性能。缺点是必须使用函数语法来访问字段,这会阻止例如field &= value - 你必须使用例如obj.field(obj.field() & value)

标签: binary-serialization binary-deserialization


【解决方案1】:

您可以为此考虑 ASN.1 并使用 PER(对齐或未对齐)。您可以使用限制为所需长度的 BIT STRING 类型,或使用带有约束的 INTEGER 类型来将值限制为您想要的位数。由于 ASN.1 及其编码规则独立于机器架构和编程语言,因此您不必担心您的机器是大端还是小端,或者通信的一端是否更喜欢 Java 而不是 C 或C++。一个好的 ASN.1 工具可以为您处理所有这些。您可以在ASN.1 Project page 找到有关 ASN.1 的更多信息,其中有一个链接 Introduction to ASN.1 以及 ASN.1 Tools 的列表(有些是免费的,有些是商业广告)。我提到 UNALIGNED PER 的原因是您可以根据需要准确地发送该行的位数,而无需添加任何填充位。

对于 BIT STRINGS,您甚至可以为对您的应用程序有意义的各个位指定名称。

【讨论】:

  • 是的!这个特殊的asn1c compiler 是最容易安装的,示例简短且易于破解。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多