ProtoBuffer笔记

Protobuf学习

Protobuf是什么

Protobuf是一种平台无关、语言无关、可扩展且轻便高效的序列化数据结构的协议,可以用于网络通信数据存储

为什么要使用Protobuf

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VAUA04OZ-1603160278192)(D:/images4note/2608075-1e8b5b166e9d9fee.png)]

使用方法也比较简单:

  • 定义用于消息文件.proto

  • 使用protobuf的编译器编译消息文件

  • 使用编译好对应语言的类文件进行消息的序列化与反序列化

    先来定义一个简单的消息:

    message Person {
       int32 id = 1;//24
       string name = 2;//wujingchao
       string email = 3;//wujingchao92@gmail.com
    }
    

    实际的二进制消息为:

    08 18 12 0a 77 75 6a 69 6e 67 63 68 61 6f 1a 16 77 75 6a 69 6e 67 63 68 61 6f 39 32 40 67 6d 61 69 6c 2e 63 6f 6d

    其实Protobuffer就是把数据转换成2进制的数据,这样传输效率会大大提高!!

    使用步骤:

    先在Java的同级目录下新建一个名为proto的文件夹专门用于存放proto文件,编写proto文件后编译模块会根据proto文件内容生成java文件。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-byuMT92w-1603160278195)(D:/images4note/2608075-1e8f6b397107fd56.png)]

来看一下名为Test.proto的文件内容:

//指定protobuf语法版本
syntax = "proto2";

//包名
option java_package = "com.lhc.protobuf";
//源文件类名
option java_outer_classname = "AddressBookProtos";

// class Person
message Person {
  //required 必须设置(不能为null)
  required string name = 1;
  //int32 对应java中的int
  required int32 id = 2;
  //optional 可以为空
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }
   //repeated 重复的 (集合)
  repeated PhoneNumber phones = 4;
}

message AddressBook {
  repeated Person people = 1;
}

Protobuf应用------网络传输

http传输

通常在应用层我们使用的都是Http协议,Http的本质是一次socket请求的连接与断开。传输数据时将protobuf对象转换为byte[]传输即可

自定义TCP通信协议

当我们自定义TCP通信协议的时候,将面临粘包与分包的问题

分包:

  • 要发送的数据大于TCP缓冲剩余空间

  • 待发送数据大于MSS(最大报文长度)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r7m6au50-1603160278198)(D:/images4note/2608075-120dfd45169eb074.webp)]

粘包:

  • 要发送的数据小于TCP缓冲区,将多次写入缓冲区的数据一起发送
  • 接收端的应用层没有及时读取缓冲区的数据

自定义通信协议的两种方式

  • 定义数据包包头

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wWbO0e5H-1603160278201)(D:/images4note/2608075-43774effe82958aa-1553651810415.png)]

  • 在数据包之间设置边界

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Jj84Xgy-1603160278204)(D:/images4note/2608075-4ae26be105ab8167.webp)]

​ 大家可以参考 JT808协议 ------交通部808协议(车联网),也是采用类似的方式定义通信协议


小细节:

枚举enum类型:

1、不支持一个proto文件中,多个枚举中定义相同的枚举常量名。
enum Enum1 {
    IDLE = 0;
    RUNNING = 1;
}

enum Enum2 {
    IDLE = 5;
    RUNNING = 6;
}

编译不通过,会报错!!!

2、枚举第一个常量的值必须是0

eg:

enum BallTypeEnum {
    BALL_TYPE_UNSPECIFIED = 0;
    BASKETBALL = 1;
    FOOTBALL = 2;
}

报错!!!==

2、枚举第一个常量的值必须是0

eg:

enum BallTypeEnum {
    BALL_TYPE_UNSPECIFIED = 0;
    BASKETBALL = 1;
    FOOTBALL = 2;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值