protobuf 语法详解(含代码案列)

41 篇文章 6 订阅
3 篇文章 0 订阅

文档声明:
以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正。并且该文档在后期会随着学习的深入不断补充完善。感谢各位的参考查看。


笔记资料仅供学习交流使用,转载请标明出处,谢谢配合。
如果存在相关知识点的遗漏,可以在评论区留言,看到后将在第一时间更新。
作者:Aliven888

1、简介

protobuf (全称:protocol buffer) 是谷歌内部的混合语言数据标准。通过将结构化的数据进行序列化(串行化),用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

2、优点:

性能方面:

  • 序列化后,数据大小可缩小3倍。
  • 序列化速度快。
  • 传输速度快。

使用方面:

  • 使用简单, proto 编译器自动进行序列化和反序列化。
  • 维护成本低:对平台只要维护一套对象协议文件,即 xx.proto 文件。
  • 可扩展性好:不必破坏旧的数据格式,就能对数据结构进行更新。
  • 加密性好:http 传输内容抓包只能抓到字节数据。

使用范围:

  • 跨平台、跨语言、可扩展性强。

3、proto 文件基础语法

3.1、message 介绍

messageprotobuf 中定义一个消息类型是通过关键字 message 字段指定的,这个关键字类似于 C++/Java 中的 class 关键字。使用 protobuf 编译器将 proto 编译成 C++ 代码之后,每个 message 都会生成一个名字与之对应的 C++ 类,该类公开继承自 google::protobuf::Message

3.2、message 消息定义

// 表示当前使用的是 proto2 指令
syntax = "proto2";

// 包声明,在生成的代码文件中是 域名。
package AlivenMsg;

message AlivenInfo 
{
	required string name = 1;   // 位置1
	optional int32 age = 2;     // 位置2
	
	message PhoneInfo
	{
		required string number = 1;
		optional int32 type = 2;
	}
	
	repeated PhoneInfo phone = 3;  // 位置3
}

3.3、message 字段介绍

3.3.1、包声明

proto 文件以 package 声明开头,这有助于防止不同项目之间命名冲突。在 C++ 中,以 package 声明的文件内容生成的类将放在与包名匹配的 namespace 中,上面的 xx.proto 文件中所有的声明都属于 AlivenMsg

3.3.2、字段介绍
  • required:消息体中必填字段,不设置会导致编解码异常。(例如位置1)。
  • optional: 消息体中可选字段,可通过default关键字设置默认值。(例如位置2)。
  • repeated: 消息体中可重复字段,重复的值的顺序会被保留(例如位置3)。
3.3.3、标识号

标识号: 在消息体的定义中,每个字段都必须要有一个唯一的标识号,标识号是 [0,2^29-1] 范围内的一个整数。以 AlivenInfo 为例,name=1,id=2, email=3, phones=4 中的 1-4 就是标识号。

3.3.4、数据定义

  许多标准的简单数据类型都可以用作 message 字段类型,包括 bool、int32、float、doublestring

  还可以使用其他 message 类型作为字段类型在消息体中添加更多结构。在上面的示例中,AlivenInfo 包含 PhoneInfo message (即 PhoneInfo 定义在 AlivenInfo 中。

4、编译 xx.proto 文件

  可以使用 protoc 指令对 xx.proto 文件进行编译,生成对应的 C++ 文件

# 语法 1
protoc -I=./ --cpp_out=./ xx.proto

# 语法 2
protoc xx.proto -I=./ --cpp_out=./ 

# -I : xx.proto 文件所在的位置。
# --cpp_out : xx.proto 生成的 C++ 代码文件存放位置。
# xx.proto : 需要编译的 xx.proto 目标文件。

# 编译后会在 ./ 路径下生成两个文件;xx.pb.h 和 xx.pb.cc

5、序列化 与 反序列化

序列化: 将数据结构或者对象转换成二进制串的过程。
反序列化: 将在序列化过程中所产生的的二进制串转换成数据结构或者对象的过程。

API 介绍:
  这里先简单介绍几个常用的 API,以便帮助理解,后面会在出一篇专业的 API 的帖子。

// 序列化常用 API 
std::string SerializeAsString() const;
bool SerializeToString(std::string* output) const;
bool SerializeToArray(void* data, int size) const;

// 反序列化常用 API
bool ParseFromArray(const viod* data, int size);
bool ParseFromString(const std::string& data);
bool ParseFromIstream(std::istream* input);

6、Demo 附件

  这里附上一个自己开发的一个小 demo,仅供参考。

  Demo 环境部署请参考《Ubuntu 20.04 系统中 protobuf 的部署与安装》这篇帖子。

链接:https://pan.baidu.com/s/1_9R4mEQA8fjAxen0FYNyzg?pwd=6l5o 
提取码:6l5o
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值