我是靠谱客的博主 魔幻发夹,最近开发中收集的这篇文章主要介绍ProtoBuffer笔记Protobuf学习小细节:,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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学习小细节:所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部