从部分 google protobuf 消息中检索信息

Retrieve information from partial google protobuf message

我正在从事一个项目,该项目涉及分别使用 C++ 和 python 编写的两个应用程序之间的通信。他们将使用 google 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字段呢?例如,如果现在在我的缓冲区中,只有 lenname_len,我可以使用

raw_msg.ParseFromString(buffer)

raw_msg.len()得到len值?

您需要单独对长度进行编码,而不是将其作为消息本身的一部分。通常不能保证仅因为 len 的字段编号为 1,它就会在其他字段之前进行编码——事实上,它出现在消息的末尾或中间的任何位置都是合法的。

您可能想要做的是遵循半标准 "delimited" 格式,在这种格式中,您在对消息本身进行编码之前将消息的长度编码为 "varint"。 "varint" 是可变长度的 base-128 整数,如 protobuf 文档中所述。不幸的是,我不确定 Python API 是否有可公开访问的辅助方法来对此进行编码(C++ 和 Java 有)。

另一方面,考虑使用 oneof 声明来区分不同的正文消息类型,而不是使用类型名称和字符串。 oneof 类型更安全,更容易理解,在线上编码更有效,并且避免了 double-parse/encode.