protobuffer 协议分析

ProtoBuffer 协议中数据经过序列化之后生成的二进制流非常紧凑,这个得益于Varint,Varint 是一种表示数字的紧凑型方法,它用一个或者多个字节表示一个数字,越小的数字字节越少

Varint编码中最高位bit(msb)有特殊含义,如果该位为1,表示后续byte也是该数字的一部分,以此类推,如下图以300为例,第一个字节msb 位是1,表示后续的byte也是该数字的一部分,第二个字节msb位为0,表示该数字结束。

1010 1100 0000 0010
→ 010 1100  000 0010

然后将两个字节剩余7位进行交换拼接,因为 varint 存储数据是以 least significant 方式

000 0010  010 1100
→  000 0010 ++ 010 1100
→  100101100
→  256 + 32 + 8 + 4 = 300

那么再看二进制流的结构,可以看成是 key-value 形式的数据

key是通过 fieldNumber 和 wireType 计算出来的

key = field_number << 3 | wireType

value 表示的是值,如图所示:

image

wiretype 如下图所示

image

经验:解析的时候对应每一个Proto java文件,都在 dynamicMethod 方法中进行解析, 先读取 tag,可以通过 WireFormat 类将 tag 解析为 fieldNumber 和 wireType,可查看协议是否是对的。

参看资料

https://developers.google.com/protocol-buffers/docs/encoding

https://github.com/google/protobuf

https://developers.google.com/protocol-buffers/docs/reference/java-generated

http://blog.csdn.net/wangqiuyun/article/details/42119835