5

我正在寻找一种将 C++ 数据包序列化为网络流的解决方案。

我在这里看到很多帖子提到人们:

  1. 高手

  2. Google 协议缓冲区

  3. Boost::序列化

  4. Qt ::QDataStream

我的要求/限制:

  1. 解决方案必须不知道 LitteEndian/BigEndian。机器架构 x86/x64 和平台无关。

  2. 前 3 个解决方案的占用空间(RAM 和 ROM)对于我的平台来说太大了,第四个与下一个要求相冲突。

  3. 该解决方案不需要大量样板代码(将有 200 多个数据包要序列化)。

谢谢,科比·梅尔

4

5 回答 5

13

如果您发现 Google Protocol Buffers 太重(我同意这一点,因为编译的库可能需要超过 1 MB),您可以尝试小几倍的 protobuf精简版。可以通过插入以下行在 *.proto 文件中启用它

option optimize_for = LITE_RUNTIME;

但是,如果您需要一个开销最小的 protobuf 解决方案,我会选择protobuf-c
它是 protobuf 的 C 实现。使用起来会有点困难,但二进制代码大小开销应该是最小的(30-50 KB)。我知道这个 C 实现例如被umurmur使用——一个在嵌入式 Linux ARM 和 MIPS 路由器上运行良好的语音服务器。

于 2011-04-11T16:19:09.850 回答
1

另一个想法:序列化为文本,在另一边解析。

我们经常这样做(TCP、UDP、串行、其他协议)。这种方法具有极大的优先级,例如在机器人控制系统、实验室信息管理系统以及许多供应商之间“挂钩”有用的任何其他地方:每个人都只发送纯文本(ASCII 或 UTF-8),它是易于阅读,易于调试,易于逆向工程,易于修复/连接。(如果您希望它不透明,您可以加密您的有效负载,例如使用公钥/私钥。)

这符合您对 endien-ness/不同平台要求的要求。我们使用了 XML,它运行良好并且相当“标准”,带有一些参考本体,用于您想要的(可能是嵌套的)“Key=Value”值,但我们倾向于使用 INI 样式的格式,使用“命名部分” “因为它变得更加复杂。如果您“嵌套”很多东西,您可能会查看类似 JSON 的实现(这真的很容易)。

强烈投票支持 ASCII,恕我直言。

于 2011-04-11T16:30:42.700 回答
1

哇,ACE,boost 序列化……这些框架内置了序列化,但是仅仅看它们进行序列化就像买车,因为你需要 CD 播放器。SUN/DEC RPC 使用一种称为 XDR 的格式——在 Steven 的“UNIX 网络编程”中有很好的描述——本质上它是一个 1000 LOC 的 header/c 文件。你可以单独使用。CORBA 在下面也使用 XDR。只需在 Google 代码中查找“xdr.h”——大量的 OSS 实现。如果您仍然需要一些复杂的东西,我会发现 ASN.1 是最全面的解决方案,它比大多数应用程序所需的复杂一点,但是 ASN.1 编译器生成紧凑的代码。它主要用于电信堆栈、电话、GSM 消息等。ASN.1 用于编码 RSA 密钥。

于 2011-04-16T18:39:25.723 回答
0

我认为您必须推出自己的最终解决方案,但您可以使用一些构建块:

  • Boost::Spirit(Karma 用于序列化,Qi 用于反序列化)
    对您来说可能仍然太大,在这种情况下,您必须自己滚动以进行序列化/反序列化,尽管您可以使用Barton-Nackman 习语来保持代码可读并且仍然使用简单的serialize函数
  • 一个轻量级的通信层,例如Arachnida(您可以仅将其用于通信,而无需使用其 HTTP 工具)。
    Arachnida 建立在 OpenSSL 之上。如果这对你来说也太重了,你真的应该自己动手。

对小/大字节序的无知/知识几乎掌握在您的序列化代码手中。

祝你好运

于 2011-04-11T15:53:12.583 回答
0

我使用微软在MFC中使用的相同技术实现了类似的东西。基本上,您在每个可序列化类中实现方法来序列化和反序列化您想要从该类中保存的任何内容。它非常轻巧且快速。

我没有使用微软使用的“归档”类,而是使用了二进制流类。我的要求不需要字节序意识,但如果您实现一个基类来序列化 POD 变量,那么实现起来将是微不足道的。

于 2011-04-11T17:19:19.423 回答