protobuf详解

2023-05-16

1 protobuf 简介

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

我们说的 protobuf 通常包括下面三点:

  • 一种二进制数据交换格式。可以将 C++ 中定义的存储类的内容与二进制序列串相互转换,主要用于数据传输或保存

  • 定义了一种源文件,扩展名为 .proto(类比.cpp文件),使用这种源文件,可以定义存储类的内容

  • protobuf有自己的编译器protoc,可以将 .proto 编译成.cc文件,使之成为一个可以在 C++ 工程中直接使用的类

序列化:将数据结构或对象转换成二进制串的过程。

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

2 定义proto文件

2.1 message 介绍

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

2.2 message 消息定义

创建tutorial.person.proto文件,文件内容如下:

// FileName: tutorial.person.proto 
// 通常文件名建议命名格式为 包名.消息名.proto // 表示正在使用proto2命令
syntax = "proto2"; 

//包声明,tutorial 也可以声明为二级类型。例如a.b,表示a类别下b子类别
package tutorial; 

//编译器将生成一个名为person的类
//类的字段信息包括姓名name,编号id,邮箱email,以及电话号码phones
message Person { 

  required string name = 1;  // (位置1)
  required int32 id = 2;  
  optional string email = 3;  // (位置2)

  enum PhoneType {  //电话类型枚举值 
    MOBILE = 0;  //手机号  
    HOME = 1;    //家庭联系电话
    WORK = 2;    //工作联系电话
  } 
  
  //电话号码phone消息体
  //组成包括号码number、电话类型 type
  message PhoneNumber {
    required string number = 1;    
    optional PhoneType type =  2 [default = HOME]; // (位置3)
  }  
  
  repeated PhoneNumber phones = 4; // (位置4)
} 


// 通讯录消息体,包括一个Person类的people
message AddressBook { 
  repeated Person people = 1; 

}

2.3 模块说明

2.3.1 包声明

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

2.3.2 字段规则

  • required:消息体中必填字段,不设置会导致编解码异常。(例如位置1)

  • optional: 消息体中可选字段,可通过default关键字设置默认值。(例如位置2)

  • repeated: 消息体中可重复字段,重复的值的顺序会被保留(例如位置3)。其中,proto3默认使用packed方式存储,这样编码方式比较节省内存。

2.3.3 标识号

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

2.3.4 数据定义

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

还可以使用其他message类型作为字段类型在消息体中添加更多结构。在上面的示例中,Person包含PhoneNumber message, 而AddressBook包含Person message

甚至可以定义嵌套在其他message中的message类型。例如,上面的PhoneNumber定义在Person中。

2.3.5 message自带方法

message关键字声明的的消息体,允许你检查、操作、读、或写整个消息,包括解析二进制字符串,以及序列化二进制字符串。除此之外,也定义了下列方法:

Person:缺省的构造函数。

~Person():缺省的析构函数。

Person(const Person& other):拷贝构造函数。

Person& operator=(const Person& other): 赋值 (Assignment )操作符。

const UnknownFieldSet& unknown_fields() const:
返回当解析信息时遇到的未知字段的集合。

UnknownFieldSet* mutable_unknown_fields():
返回当前解析信息时遇到的未知字段的集合的一个mutable指针。

3 编译proto文件

可以执行以下protoc命令对.proto文件进行编译,生成对应的c文件。Linux系统通过 protoc -help 查看protoc命令的使用详解。

protoc -I=$SRC_DIR --cpp_out=$DST_DIR  xxx.proto 
  • $SRC_DIR 所在的源目录

  • --cpp_out 生成C++代码

  • $DST_DIR 生成代码的目标目录

  • xxx.proto:要针对哪个proto文件生成接口,在这里对应 tutorial.person.proto

编译完成后,将生成2个文件 tutorial.pb.htutorial.pb.c 其中tutorial表示包名,pb是protobuf的缩写。

此外,protocol buffer 编译器为.proto文件中定义的消息的每个字段生成一套存取器方法

对于 message Person 中的 required int32 id = 2,编译器将生成下列存取器方法

bool has_id() const: 用于判断字段id是否存在。如果字段被设置,返回true。

int32 id() const: 返回字段id的当前值,如果字段没有被设置,返回缺省值。

void set_id(int32 value) : 设置字段id的值。调用此方法后,has_id() 将返回true以及id() 将返回value

void clear_id():清除字段的值。调用此方法后,has_id()将返回false 以及id()将返回缺省值。

当然,对于其他类型的字段,编译器也会生成不同的存取方法,这里就不一一列举了。

4 使用message

//获取person实例:
tutorial::AddressBook addressBook;
Person *person = 
addressBook.add_people(); 

//写入一个message:
person->set_id(id);
getline(cin,*person->mutable_name());

//读取一个message: 
person.id();
person.name();
person.email(); 

扩展一个message:

  • 你不得更改任何现有字段的字段编号

  • 你可以删除optionalrepeated属性的字段

  • 你可以添加新的optionalrepeated字段,但必须使用新的标记

5 protobuf的优点

性能方面

  • 序列化后,数据大小可缩小3倍

  • 序列化速度快

  • 传输速度快

使用方面

  • 使用简单:proto编译器自动进行序列化和反序列化

  • 维护成本低:多平台只需要维护一套对象协议文件,即.proto文件

  • 可扩展性好:不必破坏旧的数据格式,就能对数据结构进行更新

  • 加密性好:http传输内容抓包只能抓到字节数据

使用范围

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

6 总结

C++ protocol buffers 已经做了极大优化,当然它的用途不仅仅是简单的访问器和序列化,如果运用好自己的想象力,可以将protobuf应用于更广泛的问题中。

protobuf详解 (qq.com)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

protobuf详解 的相关文章

  • 【gRPC】Protobuf中间文件介绍、使用、Go新版本TLS证书认证问题

    文章目录 前言一 gRPCSANCA根证书生成服务端证书签发 二 总结三 参考 前言 初学gRPC xff0c 跟着B站go语言grpc框架实战Up主进行学习 xff0c 其中视频中的坑还是比较多的 xff0c 比如版本方法废弃 xff0c
  • 编译protobuf v3.20.0

    https github com protocolbuffers protobuf git clone git 64 github com protocolbuffers protobuf git cd protobuf git check
  • 消息序列化工具-protobuf介绍及安装使用技巧

    简介 protobuf是google团队开发的用于高效存储和读取结构化数据的工具 xml json也可以用来存储此类结构化数据 xff0c 但是使用protobuf表示的数据能更加高效 xff0c 并且将数据压缩得更小 xff0c 大约是j
  • 使用Zeromq和protobuf实现的socket通信

    本文介绍使用ZeroMQ 下文简称ZMQ 结合protobuf序列化实现客户端和服务端的通信 在之前的一篇文章中 http blog csdn net cjf wei article details 52894560 介绍了Google的p
  • Protobuf生成Go代码指南

    这个教程中将会描述protocol buffer编译器通过给定的 proto会编译生成什么Go代码 教程针对的是proto3版本的protobuf 在阅读之前确保你已经阅读过Protobuf语言指南 编译器调用 Protobuf核心的工具集
  • protobuf详解

    1 protobuf 简介 protobuf protocol buffer 是谷歌内部的混合语言数据标准 通过将结构化的数据进行序列化 串行化 xff0c 用于通讯协议 数据存储等领域和语言无关 平台无关 可扩展的序列化结构数据格式 我们
  • vs2015的OpenCV3.2.0编译

    我们希望添加第三方功能模块和库或者针对特定cpu和gpu的编译调整优化选项 这样的需求就需要自己去编译opencv了 准备东西 opencv opencv contrib cmake 还有两个文件 因为可能是国内的原因 在configure
  • mac下编译protobuf c++

    由于protobuf官网的文档是英文版的 并且并没有比较详细的说明 可能说得很清楚了 只是我这种英文渣看不懂 学习起来着实费了一翻功夫 在此 记录一下学习过程 希望尽量详细 一 编译过程需要的工具 1 protobuf源码 下载地址 htt
  • protobuf版本冲突问题解决

    1 proto caffe pb h 17 2 error error This file was generated by an older version of protoc 如果你装有anaconda 以及tensorflow 或者在
  • protobuf 2.0版本排查必填字段未填的方法

    在proto2 0版本中 如果required字段没有填写 那么proto编码字符串发给对方进行parse时 对方会parse失败 因此有必要在发送前检查一下是否存在这种情况 特别是在debug阶段 1 为了获取proto序列化的错误信息
  • c++ protobuf 可能会遇到的坑

    1 发现存在内存泄露 程序退出时记得调用 google protobuf ShutdownProtobufLibrary 这里一定是在程序退出时调用 如果调用后又使用了 protobuf 会出现异常 因为protobuf 中使用构造 会有创
  • Protobuf(Protocol Buffers)超详细入门教程(跨平台序列化, Java)——更新于2022.01

    目录 相关教程 相关文献 安装 C Installation Unix 环境 Protobuf3 0基础上手例子 相关教程 Protobuf Protocol Buffers 超详细入门教程 跨平台序列化 C CMake 更新于2022 0
  • mac环境下Maven实现ProtoBuf编译

    mac环境下Maven实现protobuf编译 1 Maven项目创建 File gt new gt Project gt 输入项目名称 gt finish 2 在项目中创建proto目录 该目录用来保存 proto文件 此处将proto目
  • gRPC的介绍、安装与使用

    1 gRPC是什么 在 gRPC里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法 使得您能够更容易地创建分布式应用和服务 与许多 RPC系统类似 gRPC也是基于以下理念 定义一个服务 指定其能够被远程调用的方法
  • Protobuf在java中的简单使用实例

    TTprotobuf是一种跨语言的数据转换协议 由google开源的 已支持大部份语言 在一般的数据交互过程中都是使用json xml等来做数据的转换 这其中涉及复杂的解析与序列化反序列化问题 如果在大量数据并发请求时 也会导致性能问题 p
  • Protobuf下载和编译

    系列导航 一 Protobuf下载和编译 二 Protobuf在Java中的简单使用 一 简介 protobuf全称Google Protocol Buffers 是google开发的的一套用于数据存储 网络通信时用于协议编解码的工具库 是
  • protobuf安装教程

    protobuf安装 一 Windows下安装 下载protobuf 配置环境变量 检查是否安装成功 二 Linux下安装 下载protobuf 安装protobuf 检查是否安装成功 一 Windows下安装 下载protobuf 下载地
  • Ubuntu 下配置protobuf

    首先得到 protobuf 相应的包文件 在终端上输入如下 wget http protobuf googlecode com files protobuf 2 5 0 tar gz 由于 现在 protobuf 2 5 0 tar gz已
  • protobuf在C#项目中的使用

    protobuf在C 项目中的使用 在C 项目中 有时候会使用到使用到protobuf来作为通信时数据交换的格式 protobuf ProtocolBuffer 简称PB 是google 的一种数据交换的格式 这是一种二进制的格式 比使用x
  • C++使用protobuf实现序列化与反序列化

    一 protobuf简介 1 1 protobuf的定义 protobuf是用来干嘛的 protobuf是一种用于 对结构数据进行序列化的工具 从而实现 数据存储和交换 主要用于网络通信中 收发两端进行消息交互 所谓的 结构数据 是指类似于

随机推荐

  • 重新认识 IP地址

    目录 一 什么是网段划分 二 如何分配子网中的IP xff1f 三 IP地址的分类 1 早期划分方式 1 早期分类方式 2 早期分类的局限性 2 CIDR划分 xff08 子网掩码划分 xff09 1 基本思路 2 实现方式 四 IP地址的
  • Linux服务器下抓包工具tcpdump分析

    概述 说到抓包分析 xff0c 最简单的办法莫过于在客户端直接安装一个Wireshark或者Fiddler了 xff0c 但是有时候由于接口调用无法在客户端抓包 xff0c 只能在服务器上抓包 xff0c 这种情况下怎么办呢 xff1f 本
  • MATLAB 常用转义字符

    MATLAB常用转义字符收录如下 Single quotation mark nbsp Percent character nbsp Backslash nbsp a Alarm nbsp b Backspace nbsp f Form f
  • 利用MATLAB解决人工神经网络模拟预测问题研究

    利用MATLAB解决人工神经网络模拟预测问题研究 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 人工神经网络根据模仿人脑的工作原理抽象出来的一种算法 人工神经网络 artigicial neutral ne
  • Visual Studio 2008学习过程(之一)起步

    以前 xff0c 在使用MATLAB开发一些软件 xff0c 虽然它的数值计算方面的功能很强大 xff0c 但是界面不是很好看 xff0c 很难做出来漂亮的软件 xff0c 所以萌生了用VS和MATLAB联合编程的想法 这样可以使软件更加强
  • 如何用servlet写网页访问量计数器?

    如何用servlet写网页访问量计数器 xff1f 1 原料 l MyEclipse l Tomcat l html 2 步骤 1 新建工程 项目栏鼠标右键 New Web Project xff0c 这里我起名为 xff1a myexm4
  • 提示:请安装TCP/IP协议.error=10106。解决方案

    有朋友使用电脑的时候会出现如下错误 xff0c 如何解决该问题是本文写作的目的 提示错误 xff1a 图 1 解决 方案 xff1a 1 删除两个注册表选项 xff1b 按下windows键 43 R键 xff0c 输入regedit xf
  • 防止头文件被重复包含

    前言 为了避免同一个文件被include多次 xff0c C C 43 43 中有两种方式 xff0c 一种是 ifndef方式 xff0c 一种是 pragma once方式 方式一 xff1a ifndef SOMEFILE H 或写为
  • 有趣的网站分享——pornhub风格生成器

    寄语 要说logo设计 xff0c pornhub的logo设计让人印象深刻 xff0c 黑底白字 xff0c 配上一小撮橙色 xff0c 给人极强的冲击力 这不 xff0c 有一个有意思的程序员弄了一个网站 xff0c 专门生成pornh
  • 大小端存储问题

    1 什么是数据的高低位 数据的高位在左 xff0c 低位在右 2 什么是内存的高低位 2 什么是大端存储 小端存储 简单记就是 xff1a 小端 xff1a 低低 xff08 数据低位在内存低位 xff09 大端 xff1a 高低 xff0
  • 【A星算法的优化方案】

    当地图很大的时候 xff0c 或者使用A星算法的寻路频率很高的时候 xff0c 普通的A星算法就会消耗大量的CPU性能急剧下降 xff0c 普通的A星性能还是不过关 接下来我们讲讲A星寻路在遇到性能瓶颈时的优化方案 一 长距离导航 当距离很
  • Java工具类:String与DateTime类型的相互转换

    1 String 转 DateTime 在转换之前需要引入 hutool 依赖 String datestr 61 34 2022 5 19 34 DateTime datetime 61 DateUtil parse datestr 2
  • Iterator迭代器的一般用法

    Iterator迭代器的一般用法 迭代器 xff08 Iterator xff09 迭代器是一种设计模式 xff0c 它是一个对象 xff0c 它可以遍历并选择序列中的对象 xff0c 而开发人员不需要了解该序列的底层结构 迭代器通常被称为
  • socket编程---fgets和fputs函数使用理解

    这一节是继续上一节socket05的讨论 xff0c 来探讨在使用socket进行通信中遇到的一些函数使用理解误区 1 fgets的使用注意点 在写socket通信 xff08 代码见上一篇中 xff0c 只是将sendbuf和recvbu
  • Tarjan算法详细讲解

    Tarjan算法讲解的博客网上找到三篇比较好的 现在都转载了 个人只研究了第一篇 正如博主所说 讲的标比较详细 清晰 剩下两篇也可以看一下 卿学姐视频讲解 https www bilibili com video av7330663 以下内
  • 中文乱码在线恢复网站

    乱码恢复
  • GCC自带的一些builtin内建函数

    title GCC自带的一些builtin内建函数 date 2021 02 27 18 57 00 description 一些GCC自带的内建 bulitin 函数的接口及实现 一 GCC内建函数 最近在刷 leetcode 的时候遇到
  • Shell脚本实用小技巧-教你屏蔽执行命令的所有显示信息,包含错误信息

    前言 xff1a 在Linux中 xff0c 有个 dev null的东西 xff0c 人们一般称之为黑洞 xff0c 大概的意思就是东西就像黑洞一样 xff0c 任何东西丢进去都会消失 xff0c 那么下面就开始进行一些小案例去认识一下这
  • MPU6050应用详解

    MPU6050应用详解 最近项目上要用到 MPU6050 陀螺仪 xff0c 以前没有接触过它 虽然在网上很容易就可以找到了需要的代码 实现了一部分功能 但是却还是对陀螺仪的工作原理不太了解 xff0c 它的代码也需要分析一下 xff0c
  • protobuf详解

    1 protobuf 简介 protobuf protocol buffer 是谷歌内部的混合语言数据标准 通过将结构化的数据进行序列化 串行化 xff0c 用于通讯协议 数据存储等领域和语言无关 平台无关 可扩展的序列化结构数据格式 我们