文档声明:
以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正。并且该文档在后期会随着学习的深入不断补充完善。感谢各位的参考查看。
笔记资料仅供学习交流使用,转载请标明出处,谢谢配合。
如果存在相关知识点的遗漏,可以在评论区留言,看到后将在第一时间更新。
作者:Aliven888
文章目录
1、简介
protobuf
(全称:protocol buffer
) 是谷歌内部的混合语言数据标准。通过将结构化的数据进行序列化(串行化),用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。
2、优点:
性能方面:
- 序列化后,数据大小可缩小3倍。
- 序列化速度快。
- 传输速度快。
使用方面:
- 使用简单,
proto
编译器自动进行序列化和反序列化。 - 维护成本低:对平台只要维护一套对象协议文件,即
xx.proto
文件。 - 可扩展性好:不必破坏旧的数据格式,就能对数据结构进行更新。
- 加密性好:
http
传输内容抓包只能抓到字节数据。
使用范围:
- 跨平台、跨语言、可扩展性强。
3、proto 文件基础语法
3.1、message 介绍
message
是 protobuf
中定义一个消息类型是通过关键字 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、double
和 string
。
还可以使用其他 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