protobuf 是google开源的一个序列化框架,类似xml,json,最大的特点是基于二进制,比传统的XML表示同样一段内容要短小得多。还可以定义一些可选字段,用于服务端与客户端通信。前面几篇文章说了protobuf的用法,看到网上也没有分析protobuf协议的文章,就利用一些时间写了protobuf 的协议分析,希望大家喜欢。
protobuf协议核心思想
基于128bits的数值存储方式(Base 128 Varints)
数据表示方式:每块数据由接连的若干个字节表示(小的数据用1个字节就可以表示),每个字节最高位标识本块数据是否结束(1:未结束,0:结束),低7位表示数据内容。(可以看出数据封包后体积至少增大14.2%)
数字1的表示方法为:0000 0001,这个容易理解
数字300的表示方法为:1010 1100 0000 0010
protobuf字节序是小端字节序,所以这个数字实际是0000 0010 1010 1100
1010 1100 0000 0010
→ 010 1100 000 0010
如下:
000 0010 010 1100
→ 000 0010 ++ 010 1100
→ 10 0101100
→ 256 + 32 + 8 + 4 = 300
|
基于序号的协议字段映射(类似key-value结构)
所以字段可以乱序,可缺段(记optional)
message person{
required string name = 1;
required string country = 2;
optional int32 age = 3;
}
|
效果相当于json数据:person= [{1: "john"}, {2: "USA"}, {3: 30}],其中{3: 30} 还可以不传,person还可以传成 [{2: "USA"}, {1: "john"}],对端仍旧可以正常解析。
基于无符号数的带符号数表示(ZigZag 编码)
原始的带符号数
ZigZag编码后的表示
0 |
0 |
-1 |
1 |
1 |
2 |
-2 |
3 |
2147483647 |
4294967294 |
-2147483648 |
4294967295 |
使用 zigzag 编码,充分利用基于128bits的数值存储(Base 128 Varints)的
技术,只需要加多1个位来表示符号。当绝对值小的数字非常有利,这种方式可以有效减少协议内容长度。
sint32类型编码如下:
(n << 1) ^ (n >> 31)
sint64类型编码如下:
(n << 1) ^ (n >> 63)
|
协议数据结构
protobuf怎么在一长串二进制中表示若干个数据?
做法就是每块数据前加一个数据头,表示数据类型及协议字段序号。
msg1_head + msg1 + msg2_head + msg2 + ...
数据头也是基于128bits的数值存储方式,一般1个字节就可以表示:
message Test1 {
required int32 a =1;
}
如上创建了 Test1 的结构并且把 a 设为 2,序列化好的二进制数据为:
0000 10000000 0010
|
以上数据转成十六进制也就是 08 02,其中 8 是怎么得到的?
000 1000
低3位表示数据类型:0,其他表示协议字段序号:1,加上最高位0, 结果就是8
|
数据类型的表示如下:
类型
含义
用于哪些数据类型
0 |
Varint |
int32, int64, uint32, uint64, sint32, sint64, bool, enum |
1 |
64-bit |
fixed64, sfixed64, double |
2 |
Length-delimited |
string, bytes, embedded messages, packed repeated fields |
3 |
Start group |
groups (deprecated) |
4 |
End group |
groups (deprecated) |
5 |
32-bit |
fixed32, sfixed32, float |
写在最后
protobuf的优缺点
优点前面也提到了,主要有两个:
1、序列化和反序列化效率比 xml 和 json 都高(这个protobuf 自己做了测试,链接要);
2、字段可以乱序,欠缺,因此可以用来兼容旧的协议,或者是减少协议数据。
但是字段允许乱序欠缺,反过来也是缺点。所以这里总结 protobuf两个缺点,一个跟这有关:
1、如果字段过多,或者嵌套过深,都会影响反序列化效率,解析每一块数据都要根据序号找到对应的位置然后再插入到已解析好的数据中。
2、数据基于128bits的存储方式,单块数据比较大时效率很受影响。解析数据需要取到所有字节的低7位,然后再拼成一整块数据。
以上两个缺点,特别是对于erlang这类没有指针的语言来说,代价就相当昂贵。
3、协议序号也要占空间,序号越大占空间越大,当序号小于16时无需额外增加字节就可以表示。
protobuf 分析题
最后贴一道分析题,如果看得懂,基本就了解 protobuf 的协议内容了
message Test2 {
required int32 a = 3;
}
创建了Test2结构,a 赋值 150, 结果是
0001 1000 1001 0110 0000 0001
这个数写成十进制就是 24 150 1,怎么得到这个数据?
|
参考:http://blog.csdn.net/mycwq/article/details/42060641
https://developers.google.com/protocol-buffers/docs/encoding
分享到:
相关推荐
总的来说,protobuf协议工具protoc是进行跨语言数据交换的重要工具。通过protobuf,开发者可以定义一套通用的数据模型,然后在Python和TypeScript等不同语言环境下实现高效的数据序列化和反序列化,从而简化网络通信...
Google Protobuf(Protocol Buffers)是Google开发的一种数据序列化协议,它允许开发者定义数据结构的格式,并将这些数据高效地编码和解码为二进制格式,适用于跨平台、跨语言的数据交换。Protobuf的设计目标是提高...
protobuf全称是Protocol Buffers,是由Google开发的一种数据序列化协议,它允许开发者定义数据结构,然后将数据编码为二进制格式,用于存储或网络传输。标题中的"google protobuf-3.2.0"指的是protobuf的3.2.0版本,...
使用Wireshark等工具打开此文件,可以查看Protobuf协议在网络传输过程中的实际表现。这在调试、性能优化或安全检查时非常有用,因为它揭示了数据在网络中的真实形态。 **ProtobufServer.zip和ProtobufClient.zip** ...
标题中的"protobuf-3.5.0"指的是Google开源的Protocol Buffers(简称protobuf)的3.5.0版本。Protocol Buffers是一种高效的数据序列化协议,它允许开发者定义数据结构,然后生成能够轻松地在各种数据流之间读写这些...
protobuf,全称Protocol Buffers,是Google开发的一种数据序列化协议,它允许开发者定义数据结构,然后将数据编码成二进制格式进行存储或网络传输。这个格式比XML、JSON等文本格式更紧凑,传输效率更高。Python是...
标题提到的“源代码以及protobuf文件转换工具”很可能是一个包含了protobuf协议定义文件(.proto)和相关的转换工具的资源包。这些工具可以帮助开发者将protobuf定义的数据结构转换为不同编程语言的源代码,如C++、...
Protobuf,全称为Protocol Buffers,是Google开发的一种数据序列化协议,用于高效地存储和传输数据。它提供了一种语言无关、平台无关的方式,使得应用程序可以轻松地存储、读取和交换各种类型的数据。Protobuf的主要...
protobuf是Protocol Buffers的缩写,它是一种高效的数据序列化协议,由Google开发并开源。Protocol Buffers允许开发者定义数据结构的模式(schema),然后生成相应的语言绑定(如C++、Java、Python),使得应用程序...
protobuf-decoder-master.zip是一个压缩包,包含了一个名为"protobuf-decoder-master"的...它体现了对protobuf协议的深入理解和实现,为开发者提供了一种便利的方式来处理protobuf数据,特别是在缺乏协议定义的情况下。
Protocol Buffers(简称protobuf)是Google推出的一种数据序列化协议,它提供了一种语言无关、平台无关、可扩展的结构化数据序列化方法,类似于XML,JSON等,但更小、更快、更简单。protobuf-2.5.0是protobuf的一个...
Google Protobuf(Protocol Buffers)是一种高效、灵活的数据序列化协议,它能够将结构化的数据序列化,可用于数据存储、通信协议等方面。它比XML、JSON等格式更小、更快、更简单。protobuf提供了一种语言中立、平台...
这是Google开发的一种数据序列化协议,用于结构化数据的序列化,可以看作是XML、JSON的轻量级替代品。Protobuf通过定义数据结构(.proto文件),生成对应语言的代码,使得数据能够高效地在网络间传输和存储。在...
Protocol Buffers(简称Protobuf)是由Google开发的一种数据序列化协议,它能够将结构化的数据序列化,可用于数据存储、通信协议等方面。Protobuf提供的是一种比XML更小、更快、更简单的方式来序列化和反序列化数据...
Protocol Buffers(protobuf)是Google推出的一种数据序列化协议,用于结构化数据的编码和解码。protobuf的优点包括高效、跨平台和语言无关。 1. **定义消息类型**:使用.proto文件定义消息结构,包括字段类型、...
Protocol Buffers是Google开发的一种数据序列化协议,它允许开发者定义数据结构,然后生成能够轻松读写这种结构的代码,适用于多种编程语言,包括C#。 描述中的"完整示例"提示我们,这个压缩包可能包含了一个全面...
protobuf是一种由Google开发的数据序列化协议,它能够将结构化的数据序列化,可用于网络通信、数据存储等场景,具有高效、跨平台、语言中立的特点。 在描述中提到的"protobuf-jetbrains-plugin-0.13.0",指的是该...
2. **protobuf**:全称为Protocol Buffers,是Google开发的一种数据序列化协议,可以将结构化数据序列化,可用于网络通信、数据存储等,具有高效、灵活、跨语言的特点。protobuf 2.5相较于2.4可能增加了新的功能或...
protobuf是一种高效的数据序列化协议,由Google开发,广泛应用于网络通信和数据存储。在CSHARP环境中,protobuf-csharp使得.NET开发者能够利用protobuf的功能,例如序列化和反序列化结构化的数据。 GTFS是公共交通...
这个库使得.NET开发者可以方便地使用protobuf协议,包括序列化和反序列化对象,用于网络通信、持久化存储等场景。 3. **版本r668**:每个版本号代表protobuf-net库的特定改进或修复。r668可能引入了新的功能、性能...