Protobuf是什么?

类似于json的一种数据格式,独立于语言,而且是二进制方式,所以比json更快,而且还可以直接存储一些图、树

序列化和反序列化

持久化(存到磁盘硬盘)领域中,数据存到磁盘叫序列化,从磁盘读取出来叫反序列化

网络传输领域中,数据块转字符串叫序列化,对端把字符串解析为数据块叫反序列化

客户端和服务端如何通信

比如一个结构体三个数据依次发送出去,接收端可能一下接收了三个,是无法处理的(不知道边界)

第二种情况,一次性发送出去,添加标记,这样接收端可以一次性解封装,常采用TLV (Tag Length Value)

Protobuf到底是什么

类似于刚刚说的TLV结构,是一种组织数据的格式,可以把若干数据组织成一块---> 序列化为字符串 --> 发送 --> 字符串被反序列化 --> 解析数据

Protobuf怎么安装?

只演示Linux下的安装过程

  1. github下载tar.gz包

https://github.com/protocolbuffers/protobuf/releases/tag/v21.12

我这里下载的21.12版本,比较老了,但是基本功能都能用

  1. 登录Linux服务器安装

先上传到Linux上,一般的ssh工具如Mobaxterm都有这个功能

tar -zxvf your_protobuf_package.tar.gz -C /path/to/you_want

cd /path/to/you_want

  • 需要安装c++编译器,如果其他语言版本的也要安装对应编译器,c++我用的g++编译器!

./configure

make

sudo make install

protoc --version

Protobuf如何使用?

简单示例

  1. 确定要序列化的数据,手动改成protobuf格式
Protobuf类型 c++类型 备注
double double 64位浮点数
float float 32位浮点数
int32 int 32位整数
int64 long 64位整数
uint32 unsigned int 32位无符号整数
uint64 unsigned long 64位无符号整数
sint32 signed int 32位整数,处理负数效率高于int32
sint64 signed long 64位整数,处理负数效率高于int64
bool bool 布尔
string string 字符串必须是utf-8或7-bit ASCII编码
bytes string 多字节语言,比如中文字符,用这个更好
enum enum 枚举
message object of class 自定义消息类型
  1. 根据proto语法,写入后缀proto文件中

test.proto

[root@hcss-ecs-9452 test_proto]# cat test.proto
/*
struct Person
{
string name;
string sex;
int age;
}
*/
syntax = "proto3"; message Person
{
string name = 1;
bytes sex = 2;
int32 age = 3;
}
  1. protoc命令把proto文件转成c++,包含一个xxx.pb.cc和xxx.pb.h

protoc ./test.proto --cpp_out=./

[root@hcss-ecs-9452 test_proto]#
[root@hcss-ecs-9452 test_proto]# ls
test.proto
[root@hcss-ecs-9452 test_proto]# protoc ./test.proto --cpp_out=./
[root@hcss-ecs-9452 test_proto]# ls
test.pb.cc test.pb.h test.proto
[root@hcss-ecs-9452 test_proto]#
  1. 把产生的c++文件添加到项目中,根据文件中API实现序列化和反序列化

节选test.pb.h ,这部分就是protobuf给出的对name这个数据的处理方式,比如清空 设置 查询 根据地址修改等

enum : int {
kNameFieldNumber = 1,
kSexFieldNumber = 2,
kAgeFieldNumber = 3,
};
// string name = 1;
void clear_name();
const std::string& name() const;
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_name(ArgT0&& arg0, ArgT... args);
std::string* mutable_name();
PROTOBUF_NODISCARD std::string* release_name();
void set_allocated_name(std::string* name);
private:
const std::string& _internal_name() const;
inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
std::string* _internal_mutable_name();
  1. 编写makefile

这里需要注意,protobuf大量使用c++11特性,但是centOS默认安装的是g++4.8.5编译器,可能不支持,需要在编译选项中-std=gnu++11

# 目标文件
TARGET = run # 源文件
SRC = run.cpp test.pb.cc # 编译器
CC = g++ # 编译选项
CFLAGS = -I. -lprotobuf -std=gnu++11 # 默认规则
all: $(TARGET) # 依赖关系
$(TARGET): $(SRC)
$(CC) $(CFLAGS) $^ -o $@ # 编译.proto文件生成C++源文件和头文件
test.pb.cc test.pb.h: test.proto
protoc --cpp_out=. $< # 清理规则
clean:
rm -f $(TARGET) test.pb.cc test.pb.h # 防止make删除中间文件
.PHONY: all clean
  1. 编译运行查看

可能要先设置一下环境变量

echo $LD_LIBRARY_PATH

# 如果已经设置过/usr/local/lib就不用往下走了
echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib' >> ~/.bashrc source ~/.bashrc echo $LD_LIBRARY_PATH
[root@hcss-ecs-9452 test_proto]# ls
Makefile run.cpp test.pb.cc test.pb.h test.proto
[root@hcss-ecs-9452 test_proto]# make
g++ -I. -L/user/local/lib -lprotobuf -std=gnu++11 run.cpp test.pb.cc -o run
[root@hcss-ecs-9452 test_proto]# ./run
name:Jack
sex:女
age:18

复杂应用

嵌套复合数据类型

新增一个proto文件,后续步骤和上面一致

  • 嵌套结构体直接加,嵌套数组前面加repeated就行,调用时需注意,数组要先add_xxx, set_xxx(0, xx)
[root@hcss-ecs-9452 test_proto]# cat testComplex.proto
syntax = "proto3";
message Addr
{
int32 door_num = 1;
bytes addr = 2;
} message Person
{
repeated string name = 1;
bytes sex = 2;
int32 age = 3;
Addr ad = 4;
}
[root@hcss-ecs-9452 test_proto]# cat run.cpp
#include "testComplex.pb.h" int main(){ Person p1;
p1.add_name();
p1.set_name(0, "Jack");
p1.add_name("Tom");
p1.add_name("sb"); p1.set_sex("女");
p1.set_age(18);
p1.mutable_ad()->set_addr("陕西省西安市雁塔区");
p1.mutable_ad()->set_door_num(999); std::string output;
p1.SerializeToString(&output); Person p2;
p2.ParseFromString(output);
//std::cout << "name:" << p2.name() << std::endl;
std::cout << "sex:" << p2.sex() << std::endl;
std::cout << "age:" << p2.age() << std::endl;
std::cout << "addr:" << p2.ad().addr() << p2.ad().door_num() << "号" << std::endl;
int size = p2.name_size();
for(int i = 0; i < size; ++i)
{
std::cout << "第" << i << "个名字是" << p2.name(i) << std::endl;
}
return 0;
}

使用枚举


[root@hcss-ecs-9452 test_proto]# cat testComplex.proto
syntax = "proto3";
enum Color
{
red = 0; //第一个必须是0
green = 5; //后面的不必123
blue = 6;
}
message Addr
{
int32 door_num = 1;
bytes addr = 2;
} message Person
{
repeated string name = 1;
bytes sex = 2;
int32 age = 3;
Addr ad = 4;
Color color = 9; //这里也可以不写567
}
[root@hcss-ecs-9452 test_proto]# cat run.cpp
#include "testComplex.pb.h" int main(){ Person p1;
p1.add_name();
p1.set_name(0, "Jack");
p1.add_name("Tom");
p1.add_name("sb"); p1.set_sex("女");
p1.set_age(18);
p1.mutable_ad()->set_addr("陕西省西安市雁塔区");
p1.mutable_ad()->set_door_num(999);
p1.set_color(Color::red); std::string output;
p1.SerializeToString(&output); Person p2;
p2.ParseFromString(output);
//std::cout << "name:" << p2.name() << std::endl;
std::cout << "sex:" << p2.sex() << std::endl;
std::cout << "age:" << p2.age() << std::endl;
std::cout << "addr:" << p2.ad().addr() << p2.ad().door_num() << "号" << std::endl;
int size = p2.name_size();
for(int i = 0; i < size; ++i)
{
std::cout << "第" << i << "个名字是" << p2.name(i) << std::endl;
}
std::cout << "Color:" << p2.color() << std::endl;
return 0;
}

proto中导入其他proto文件

import "/path/xxx.proto"

命名空间

package xxx

  • 当其他proto文件调用时:

    xxx.Person p

  • 上述命令会转换为cc文件的namespace

安装、学习protobuf的更多相关文章

  1. 学习protobuf

    一.认识Protobuf ref:http://blog.csdn.net/program_think/article/details/4229773摘要:1. protobuf是一个开源项目.2. ...

  2. Ubuntu安装配置protobuf 2.5

    Ubuntu安装配置protobuf 2.5 一.安装配置环境 Linux 1.安装protobuf 下载文件 https://github.com/protocolbuffers/protobuf/ ...

  3. python3数据分析,安装学习

    python3数据分析,安装学习 转载注明来源: 本文链接 来自osnosn的博客,写于 2019-09-26. 为了简单.安装 anaconda3 就好啦. 因为安装原版python3,用pip安装 ...

  4. 学习 protobuf(一)—— ubuntu 下 protobuf 2.6.1 的安装

    下载地址:https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz(如果初次下载失败,不妨多试 ...

  5. go语言学习--protobuf的学习

    最近在学习中遇到了protobuf,哇喔竟然不知道,马上进行了学习,protobuf也是数据解析的方式,平时使用最多的是json和xml,那么好了,对比下他们的区别,并且附上protobuf的使用. ...

  6. laravel安装学习步骤

    在看知乎比较php框架的优劣的时候提到为什么laravel这么好国内用的少,还有就是yii2,有人提到原因就是composer在国内无法使用.这制约了使用composer进行包管理的框架在国内的传播和 ...

  7. Sql Server 2008开发版(Developer Edition)过期升级企业版(Enterprise Edition)失败后安装学习版(Express Edition)

    最近一个多月,甚是悠哉,无事可做.上线的网站系统也没接到客户的反馈,反而觉得无聊之极了.上周五早上,一上QQ,就收到客户发来消息,管理平台无法登陆了.心里一惊,立马开始查找故障原因.翻看了系统日志,提 ...

  8. redis安装学习

    Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理.它支持字符串.哈希表.列表.集合.有序集合,位图,hyperloglogs等数据类型.内置复制.Lu ...

  9. Redis学习笔记(一)关于在windows64位环境下的安装学习使用

    前言 由于工作需要,目前我正在学习使用Redis.我当时学习Redis就从网上下载了点资料就开始学习了.入门看的是<REDIS入门指南>,这本书个人觉得很适合新手用来学习接触.根据书上的引 ...

  10. 解决p4c安装时protobuf未定义引用的错误

    安装好p4c的依赖之后,执行make -j2时出现以下问题: undefined references to `google::protobuf::internal::LogMessage::oper ...

随机推荐

  1. docker 应用篇————docker-compose[十九]

    前言 简单介绍一下docker compose. 正文 首先进行下载一下. sudo curl -L "https://github.com/docker/compose/releases/ ...

  2. bookstack书栈网docker搭建

    准备好数据后,直接运行以下命令即可. docker run -d --name bookstack \ --restart always \ --privileged=true\ -p 8181:81 ...

  3. 《c#高级编程》第2章C#2.0中的更改(三)——迭代器

    一.概念 C#迭代器(Iterator)是一种特殊类型的方法,它使得在使用循环遍历数据集合时更加简单和有效.使用迭代器可以通过简单地定义迭代器方法来自动实现枚举器模式. 当您需要访问一个数据集合中的每 ...

  4. Dapr Outbox 执行流程

    Dapr Outbox 是1.12中的功能. 本文只介绍Dapr Outbox 执行流程,Dapr Outbox基本用法请阅读官方文档 .本文中appID=order-processor,topic= ...

  5. 选轻量应用服务器or云服务器ECS?一图帮你彻底区分

    简介:轻量应用服务器适合轻量级且访问量低的应用场景,更适合个人开发者.对新手小白更友好:而云服务器ECS可覆盖全业务场景(如大数据分析,深度学习等),要求用户有一定的开发技术能力. 本文首发于公众号& ...

  6. OpenKruise v1.0:云原生应用自动化达到新的高峰

    ​简介:OpenKruise 是针对 Kubernetes 的增强能力套件,聚焦于云原生应用的部署.升级.运维.稳定性防护等领域. 云原生应用自动化管理套件.CNCF Sandbox 项目 -- Op ...

  7. 来电科技:基于 Flink + Hologres 的实时数仓演进之路

    简介: 本文将会讲述共享充电宝开创企业来电科技如何基于 Flink + Hologres 构建统一数据服务加速的实时数仓 作者:陈健新,来电科技数据仓库开发工程师,目前专注于负责来电科技大数据平台离线 ...

  8. dotnet C# 反射扫描程序集所有类型会不会触发类型静态构造函数

    在 dotnet 里面,有很多框架都喜欢扫描程序集进行初始化逻辑,在扫描程序集的所有类型的时候,相当于碰到所有类型.而某个类型的静态构造函数将会在某个类型被使用之前被 CLR 调用,那么扫描类型是否会 ...

  9. 一键启动的AI离线知识库,无需复杂环境依赖,小白都能上手了

    简介 在人工智能技术飞速发展的今天,我们经常面临一个挑战:如何快速.简便地部署和使用AI技术?AntSK项目,一个开源的AI知识库和智能体,就是为了解决这一问题而诞生的.现在,我们自豪地宣布,AntS ...

  10. vue-单独引入css文件,设置公共的css样式或者修改默认的vant,mint样式

    1.css文件夹下新建global.css文件并粘贴复制: ======================= :root{     --bgColor : #d3252a;     --pinkColo ...