Protobuff-2.0 使用

2021/12/08 Mmo-Game

Protobuff-2.0使用

目录

什么是Protobuff?

1.Protobuff是谷歌的编写的与语言无关的、平台无关、用于序列化结构化数据(如XML)可扩展的一种机制。

2.更小、更快、更简单。只需定义数据的结构方式,就可以使用特殊生成的源代码轻松地将结构化数据写入
  或从各种数据流中读取,同时支持各种语言。

3.类似xml,json,最大的特点是基于二进制,比传统的XML表示同样一段内容要短小得多。

定义一个简单的消息类型

message SearchRequest {
  required string query = 1;
  optional int32 page_number = 2;
  optional int32 result_per_page = 3;
}

每个字段都有一个名称和类型。

分配字段数字

1.在消息体中,每一个字段都会定义一个唯一的数字,这些数字用于以消息二进制格式识别您的字段。
2.从1 ~ 15范围内的字段号需要一个字节进行编码,包括字段号和字段的类型。
3.从16 ~ 2047需要暂用两个字节(ps:一个字节8位)。
4.因此,您应该为非常频繁出现的消息元素保留字段1到15。记住要为将来可能添加的频繁出现的元素留下一些空间。
5.可以指定的最小字段号是1,最大的字段号是2^29 - 1,或536,870,911。
6.不能使用 19000 ~ 19999字段号,他们是保留字段号,使用的话编译器将报错。

指定字段规则

待补充。。。

核心思想

为什么Protobuff可以实现高效快速的数据传输呢?这就归功于它的编码方式。

1.Base 128 Varints

1.什么是Varints?

1.Varints是使用一个或多个字节序列化整数的方法。较小的数字需要较少数量的字节。

2."Base 128 Varints" 可以理解为,基于一种可变字节长度的编码,也可以说是一种压缩算法。

3.除了最后一个字节,varint中的每个字节的最高位设为1,表示后面还有字节出现。
  注意最后一个字节,最高位一定是0,用来表示没有下一位了。这样一来,就可以准确的知道一个整数的结束位置。
  所以,一个字节最大表示的数字位2^7。

4.每个字节的低7位为一组,这个组和他相邻的下一个7位组共同存储某个整形的“组合表示”,最低有效组在前面。

5.压缩的依据是基于一个现实:越小的数字,越经常使用 

2.举例说明

数字1,只有一个字节,所以最高位不设置:
0000 0001
数字300:
1010 1100 0000 0010

1.第一步,除了最后一个字节去掉最高位的1(ps:最高位的1,只是表示后面还有字节),
  最后一个字节后面没有字节了所以是0,0是无效标志位也去掉:
-> 010 1100  000 0010

2.以7位为一组,两个组位置颠倒一下,因为Varints存储的低位有效组在前:
-> 0000010 0101100

3.将他们连接起来,得到最终的值:
-> 100101100
-> 1^2^8 + 1^2^5 + 1^2^3 + 1^2^2
=  256 + 32 + 8 + 4
=  300
如果基于Base 128 Varints来编码,那么4字节最大表示的数为2^28 (ps: 4字节 * 8位 - 4位 = 28位)

3.Varints优缺点

优点:
    Base 128 Varints是一种紧凑的表示数字的方法。

    它用一个或多个字节来表示一个数字,值越小的数字使用越少的字节数,
    这能减少用来表示数字的字节数。

    比如对于int32类型的数字,传统做法需要4个byte来表示,原因在于不管是多小的数字,
    为了支持最大数都会固定预留4个字节。

    但是采用 Varint,对于很小的 int32 类型的数字,则可以用1个byte来表示。

    例如:数字300
         如果用int32表示,需要4个字节,现在用 Varint 表示,只需要2个字节了,缩小了一半!
缺点:
    大的数字则需要5个byte来表示。

    解析数据需要取到所有字节的低7位,然后再拼成一整块数据, 多了转换过程。

Search

    Table of Contents