2016-12-06 143 views
0

我不得不将接口我的代码与来自我无法控制的应用程序的一些二进制协议。到目前为止,我已经从数据写入手工解析,如:用C++解析二进制协议的好库

char *data = ... 
MovementPacket pkt; 
pkt.x = data[0] | data[1] << 8; 
pkt.y = data[2] | data[3] << 8; 

很明显,这个过程很容易出错和繁琐。我记得在Java中这样做:

pkt.x = stream.readShort(); 
pkt.y = stream.readShort(); 

是否有某种库,使我能够做到这一点,考虑到endianness?

我已经看过protobuf和cap'n'proto,但是当我可以定义协议的双方都看起来很棒时,如果我必须解析特定的协议,我不确定它们会发挥出色。这是正确的还是我只是读错了资源?是否有替代方案更适合这项任务?

该协议本身是一个简单的TCP消息导向格式:从TCP流到消息的处理已经完成,我想要一些东西来解析消息本身。所有消息都以一个双字节标识字段开头,标识字段告诉消息的类型,然后是消息数据。例如,对于一个移动分组:

0x00 0x01 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x02 

[Msg. Id] [int32 X value] [int32 Y value] 

我寻找可能,给定的消息结构,它解析成一个结构,考虑到端序某些库,而无需编写手动解析代码。

+0

您的意思是“想在一侧使用生成的协议”? –

+0

@jacek我真的不明白这个问题。你在问我关于protobuf的评论吗? –

+0

如果这是新的(又名“绿色领域”)协议,不要害怕使用类似的库。我在生产中使用Thrift。非常好的类型安全代码。也许使用FlatBuffers是低配置要求。我认为没有这样的库可以帮助解析旧的“手动”协议。 –

回答

2

被警告说这个问题严重落在“高级话题”之下,但Boost.Spirit支持endian-specific binary parsing via Qi。如果你有足够的冒险精神挖掘信息来源,那么可能有些事情可以帮助你完成全部或部分任务。

协议描述有些帮助。如果原始类型都是int32这个问题很难处理。然而,在我看来,你不可能找到这个零解析代码的圣杯,因为这是一个自定义的,如果简单的协议。也许你可以将问题简化为只解析某些类型的问题 - 然后一个简单的解析器调用一系列parse(primitiveTypeValue)函数以附加到每个原语的std::vector<primitiveType>可能是可行的。

+0

是的,我已阅读http://stackoverflow.com/q/285200/1119282关于Boost.Spirit,但我真的很想找一些简单的 –

+0

了解。也许有关协议的更多细节需要解析才能找到更好的答案。 –

+0

增加了带有消息示例的编辑。这不是一个复杂的协议,只有很多不同的消息,都是由原始类型组成的。这是你问的吗? –