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. mysql 必知必会整理—游标[十四]

    前言 简单介绍一下游标. 正文 需要MySQL 5 MySQL 5添加了对游标的支持,因此,本章内容适用于MySQL 5及以后的版本. 有时,需要在检索出来的行中前进或后退一行或多行.这就是使用游标的 ...

  2. 单链表之删除头结点,查找等于定值x的结点数,单链表的逆置

    /* * @Author: 一届书生 * @Date: 2020-03-08 09:52:27 * @LastEditTime: 2020-03-08 13:58:30 */ #include < ...

  3. Flutter笔记 - 事件分发

    事件处理流程 Flutter 事件处理流程主要分两步,为了聚焦核心流程,我们以用户触摸事件为例来说明: 命中测试:当手指按下时,触发 PointerDownEvent 事件,按照深度优先遍历当前渲染( ...

  4. P7177 [COCI2014-2015#4] MRAVI 题解

    思路. 我们知道最初添加的液体越多,那么每个蚂蚁得到的液体也就越多,又因为标签里有深搜,所以可以用 DFS+二分解决(感觉说了一通废话),算是比较常规的一种解法了. 在此题中我们需要魔改一下建树,需在 ...

  5. -source 1.5 中不支持 diamond 运算符(中文版idea)

    -source 1.5 中不支持 diamond 运算符(中文版idea) 将idea中的各个部分的jdk设为8即可,中文版的如下 1.文件-设置 2.项目上右击-打开模块设置 模块中每一个都要确认是 ...

  6. 力扣34(java)-在排序数组中查找元素的第一个和最后一个位置(中等)

    题目: 给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target.请你找出给定目标值在数组中的开始位置和结束位置. 如果数组中不存在目标值 target,返回 [-1, -1]. 你 ...

  7. 力扣400(java)-第N位数字(中等)

    题目: 给你一个整数 n ,请你在无限的整数序列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...] 中找出并返回第 n 位上的数字. 示例 1: 输入:n = 3输出: ...

  8. Istio 从懵圈到熟练:二分之一活的微服务

    作者 | 声东  阿里云售后技术专家 <关注阿里巴巴云原生公众号,回复 排查 即可下载电子书> <深入浅出 Kubernetes>一书共汇集 12 篇技术文章,帮助你一次搞懂 ...

  9. Apache ShenYu 网关正式支持 Dubbo3 服务代理

    简介: 本文介绍了如何通过 Apache ShenYu 网关访问 Dubbo 服务,主要内容包括从简单示例到核心调用流程分析,并对设计原理进行了总结. 作者:刘良 Apache Dubbo 在去年发布 ...

  10. OceanBase再破纪录!核心成员陈萌萌:坚持HTAP就是坚持我们做数据库的初心

    简介: 2021年5月20日,据国际事务处理性能委员会(TPC,Transaction Processing Performance Council)官网披露,蚂蚁集团自主研发的分布式关系型数据库Oc ...