我正在开发一个项目,分别涉及c ++和python中两个应用程序之间的通信。他们将使用谷歌protobuf通过TCP进行交谈。现在,我的信息设计如下:
raw_msg
{
required int32 len = 1;
required int32 name_len = 2;
required string type_name = 3;
required bytes data = 4;
}
[other msgs....]
所以有很多消息类型,它们都会在发送之前被打包到raw_msg
中,在接收方,它将首先得到整个原始消息的len
并阻塞之前没有足够的数据。一旦数据很好地检索完整的消息,解码就会开始。
我的问题是,由于raw_msg
的长度也未修复,我如何才能获得len
字段?例如,如果现在在我的缓冲区中,只有len
和name_len
,我可以使用
raw_msg.ParseFromString(buffer)
和raw_msg.len()
获取len
值?
答案 0 :(得分:2)
您需要单独编码长度,而不是作为邮件本身的一部分。通常不能保证仅因为len
具有字段编号1,它将在其他字段之前编码 - 事实上它在消息的末尾或其间的任何地方出现是合法的。
您可能想要做的是遵循半标准"分隔"格式,其中您将消息的长度编码为" varint"在编码消息本身之前。 A" varint"是一个可变长度的基数-128整数,在protobuf文档中描述。我不确定Python API是否具有可公开访问的辅助方法来编码它,遗憾的是(C ++和Java)。
另一方面,请考虑使用oneof
声明来区分不同的正文消息类型,而不是使用类型名称和字符串。 oneof
更安全,更易于理解,更有效地在线上编码,并且无需进行双重解析/编码。