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,怎么得到这个数据?

Protobuf协议格式详解相关推荐

  1. HTTP响应协议格式详解

    文章目录 响应协议格式 1. 首行 状态码详解 2. 响应头header 响应协议格式 HTTP请求协议由首行.响应头(header).空行.正文(body)组成.通过空行来区别header和body ...

  2. UDP数据包协议格式详解

    源端口目的端口:是0-65535任何数字,在收到请求时系统会为客户端动态分配,0-1023为知名端口号 报文长度(单位4byte):表示udp报头+udp数据总长度,有别于tcp,也没有选项 UDP报 ...

  3. COAP数据包协议格式详解

    Ver:版本编号,占2bit,固定01 T:报文类型,占2bit,CON=00,NON=01,ACK=10,RST=11 CON--需要被确认的请求,如果CON请求被发送,那么对方必须做出响应. NO ...

  4. TCP数据包协议格式详解

    出一个专栏把通信协议搞一下吧,万物互联的根本呀. IP 版本4位:4(二进制0100)表示IPv4,6(二进制0110)表示IPv6 报头长度(单位4byte):因为选项长度不确定,取值范围是5-15 ...

  5. ProtoBuf格式详解

    "介绍protobuf编码格式." protobuf是一种数据交换格式,又称PB编码,由Google开源,类似于Json.XML,但其内部是纯二进制格式,比Json,XML等格式要 ...

  6. 4-4:TCP协议之TCP头部格式详解

    文章目录 一:TCP头部格式详解 (1)4位首部长度 (2)序列号和确认应答号 A:可靠性问题 B:32位序号和确认号 (3)窗口大小 (4)标志位 (5)紧急指针 A:带外数据(out_of _ba ...

  7. Memcache的使用和协议分析详解

    Memcache的使用和协议分析详解 作者:heiyeluren 博客:http://blog.csdn.net/heiyeshuwu 时间:2006-11-12 关键字:PHP Memcache L ...

  8. Gerber 格式详解

    Gerber 格式详解 gerber中文 gerber,gerber 文件:590m.com/f/25127180-487459253-79168e(访问密码:551685) 以下内容无关: ---- ...

  9. 小猫爪:嵌入式小知识10-I2S,TDM,PCM等音频格式详解

    小猫爪:嵌入式小知识10-I2S,TDM,PCM等音频格式详解 1 前言 2 I2S 3 Codec模式(左/右对齐) 3.1 左对齐(MSB对齐) 3.2 右对齐(LSB对齐) 4 DSP模式 5 ...

  10. Ffmpeg快速命令使用 Ffmpeg选项详解 Ffmepg格式详解 常见视频文件格式详解

    http://www.ffmpeg.com.cn/index.php/%E9%A6%96%E9%A1%B5 Ffmpeg快速命令使用 From Ffmpeg工程组 Jump to: navigatio ...

最新文章

  1. 用淘宝购买的win7 U盘系统给苹果笔记本Mac OS安装双系统
  2. VS2019遇到的坑——C4716
  3. url+用户名+密码_URI和URL详解
  4. 这几家公司有个梦想:开发AI操作系统,让外行也成为人工智能大师
  5. Tungsten Fabric SDN — 报文转发流程
  6. 使用jar命令查看搜索提取jar包中的文件
  7. android 模拟点击 不发出声音,【Android】代码实现模拟屏幕点击和键盘按键事件...
  8. PHP 获取JSON json_decode返回NULL解决办法
  9. windows ssh远程登录阿里云遇到permissions are too open的错误
  10. IOS学习笔记十九NSArray和NSMutableArray
  11. 消息中间件学习总结(22)——MQ 面试专题
  12. ffmpeg java 使用教程_Java使用ffmpeg
  13. Alpha 冲刺(3/10)
  14. java两周考核期被辞退_试用期被辞退,会影响一整年,或整个职场生涯
  15. 爬取网易云音乐评论过万歌曲
  16. 36-sparkstreaming
  17. 友盟APM和bugly全面对比
  18. SCAPE、BlendSCAPE、SMPL、SMPL-H、SMPL-X、STAR等都是什么?请分别仔细介绍一下
  19. 嵌入式学习(3)ADC、DMA、通信方式
  20. PAT--1051 复数乘法

热门文章

  1. Adobe flash professional CS5的序列号
  2. 负载均衡下的多台tomcat服务器,通过memcache实现session共享
  3. mysql flush explain_Mysql_mysql 性能分析及explain用法
  4. mathorcup历年优秀论文阿里云盘
  5. crx插件转换火狐插件_我的Firefox插件
  6. Windows 7下IE9升级到IE 11,F12控制台不能使用的解决方法
  7. eeg地形图matlab,Matlab画地形图
  8. 干货!网页设计中最常用的5种配图
  9. Gym 100818 F Irrational Roots (数学)
  10. RROR: Check hive‘s usability failed, please check the status of your cluster解决办法