概述
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;
}
最后
以上就是魔幻发夹为你收集整理的ProtoBuffer笔记Protobuf学习小细节:的全部内容,希望文章能够帮你解决ProtoBuffer笔记Protobuf学习小细节:所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复