python - protobuf嵌入的消息会导致额外的字节,这是分隔符吗?

标签 python protocol-buffers message encode

我正在尝试 protobuf->python 的示例代码,我有 pytest.proto

message Person{
    required string name=1;
    required int32 id=2;
    optional string email=3;

    enum PhoneType{
        mobile=0;
        home=1;
        work=2;
    }
    message PhoneNumber{
        required string number=1;
        optional PhoneType type=2[default=home];
    }
    repeated PhoneNumber phone=4;
}

编译

protoc pytest.proty --python_out=./

然后是我的 python 文件:

import pytest_pb2
import sys
person=pytest_pb2.Person()
person.name="bbb"
person.id=9

phone_number=person.phone.add()
phone_number.number="aaa"
phone_number.type=pytest_pb2.Person.work
f=open("log4py.data","w")
s=person.SerializeToString()
f.write(s)
f.close()

运行它:

$python pytest.py && xxd log4py.data
00000000: 0a03 6262 6210 0922 070a 0361 6161 1002  ..bbb.."...aaa..
          name="bbb"  id=9  ???  number="aaa" type=home

从上面我可以看到

0a03 6262 62 --> name="bbb"
1009         --> id=9
22 07        --> What's this??????????????????
0a03 616 161 --> number="aaa"
1002         --> type=home

我不明白“22 07”的额外字节在这里意味着什么,似乎表明有一个嵌入结构?所以我将我的Python程序更改为有2个“phone_number”实例,如下所示:

phone_number1=person.phone.add()
phone_number1.number="aaa"
phone_number1.type=pytest_pb2.Person.work
phone_number2=person.phone.add()
phone_number2.number="ccc"
phone_number2.type=pytest_pb2.Person.work

运行它,我得到:

$python pytest.py && xxd log4py.data
00000000: 0a03 6262 6210 0922 070a 0361 6161 1002  ..bbb.."...aaa..
00000010: 2207 0a03 6363 6310 02                   "...ccc..

好吧,这一次,我在每个 PhoneNumber 实例之前看到两次“22 07”。我知道 Protobuf 不编码任何分隔符字节,但这里似乎“22 07”是分隔符。有什么解释吗?

最佳答案

字节是子消息的标签和长度。

22 是一个标签。底部三位 (2) 指示后续字段值是长度分隔值。高 5 位 (4) 指示这是字段编号 4,即 phone 字段。

07 是长度。子消息长度为7字节。

I knew that Protobuf doesn't encode any delimeter bytes

不正确:子消息必须以某种方式分隔。 Protobuf 更喜欢使用长度前缀而不是特殊的结束标记进行分隔,因为它可以让您跳过该字段而无需解码每个字节。

关于python - protobuf嵌入的消息会导致额外的字节,这是分隔符吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41628224/

相关文章:

c++ - 带有 CMake 和静态库/Z7 标志的 Visual Studio

c - MPI_Send 和 MPI_Recv,测量 1Mb 消息的传输时间

python - OpenCV 的密集光流 (Farneback) 函数的输出是什么?这如何用于在 Python 中构建光流图?

python - 测试中的模型 - Django 1.7 问题

protocol-buffers - 您会推荐 Google Protocol Buffers 或 Caucho Hessian 用于跨语言的无线二进制格式吗?

winforms - 根据与远边缘不同的约束来调整无边界形式的大小?

javascript - Safari 扩展获取选项卡位置或标识符

python - 去抖 celery 任务?

python - 如何重新编译 python 文件

go - 如何解码被拦截的gRPC请求/响应以查看golang中已发送/已接收的protobuf消息?