protocol--2(编码)

125 阅读1分钟

官网地址

  文档地址

  学习protocol协议写入二进制格式。

简单的案例

message Test1 {
  optional int32 a = 1;
}

  protocol编码格式为TLK,tag-length-value,其中length为可选的。tag描述字段序号,与字段类型。tag为1-15占用一个byte,其中byte后三位为字段类型,前面为字段序号。

message Test1 {
  optional int32 a = 1;
}
public class Test1Main {

    public static void main(String[] args) {
        Test1.Builder builder = Test1.newBuilder().setA(150);
        Test1 build = builder.build();
        byte[] bytes = build.toByteArray();

        System.out.println("build:" + build);

        for (int i = 0; i < bytes.length; i++) {
            System.out.println("i :" + i + ",== " + Arrays.toString(CommonUtils.getBitArray(bytes[i])));
        }
    }

}


i :0,== [0, 0, 0, 0, 1, 0, 0, 0]//字段序号为8(8位后移动3位为1,对应序号为1),类型为0
i :1,== [1, 0, 0, 1, 0, 1, 1, 0]
i :2,== [0, 0, 0, 0, 0, 0, 0, 1]

  tag大于等于16占用两个byte,其中byte后三位为字段类型,前面为字段序号。

option java_multiple_files = true;
message Test2 {
  optional int32 a = 300;
}

public class Test2Main {

    public static void main(String[] args) {
        Test2.Builder builder = Test2.newBuilder().setA(150);
        Test2 build = builder.build();
        byte[] bytes = build.toByteArray();

        System.out.println("build:" + build);

        for (int i = 0; i < bytes.length; i++) {
            System.out.println("i :" + i + ",== " + Arrays.toString(CommonUtils.getBitArray(bytes[i])));
        }
    }

}

i :0,== [1, 1, 1, 0, 0, 0, 0, 0]
i :1,== [0, 0, 0, 1, 0, 0, 1, 0]
//0, 0, 1, 0, 0, 1, 0 ++ 1, 1, 0, 0, 0, 0, 0
//=2048 + 256 + 64 + 32 = 2400 tag 2400(1400位后移动3位为300,对应序号为300) ,类型为0
 
i :2,== [1, 0, 0, 1, 0, 1, 1, 0]
i :3,== [0, 0, 0, 0, 0, 0, 0, 1]

消息类型

  消息类型有以下几类。

TypeMeaningUsed For
0Varintint32, int64, uint32, uint64, sint32, sint64, bool, enum
164-bitfixed64, sfixed64, double
2Length-delimitedstring, bytes, embedded messages, packed repeated fields
3Start groupgroups (deprecated)
4End groupgroups (deprecated)
532-bitfixed32, sfixed32, float

Varints编码

  每个字节第一位代表后面是否还有数据,为0则没有,1则有。每个字节只有7个bit存储数据。

  • 案例数值 = 1
0000 0001
  • 案例数值 = 300
1010 1100 0000 0010

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

ZigZag编码

  ZigZag将有符号数,映射成无符号数。

Signed OriginalEncoded As
00
-11
12
-23
21474836474294967294
-21474836484294967295
(n << 1) ^ (n >> 31)
(n << 1) ^ (n >> 63)

String类型

  String类型,l会有值,为byte长度。

message Test2 {
  optional string b = 2;
}
  • string值为 testing
12 07 [74 65 73 74 69 6e 67]

对象类型

  对象类型,l会有值,为byte长度。

message Test3 {
  optional Test1 c = 3;
}
 1a 03 08 96 01