Learing——protobuf(一)

news2024/9/20 12:39:23

目录

前言

一、protobuf的简介

二、编写一个.proto文件

1.选择使用的protobuf版本

2.指定命名空间(package)

3.定义一个“消息”(message)

4.定义消息字段

标量类型:

枚举类型(enum):

多选一类型(oneof):

映射类型(map):

泛型类型(Any):

数组(reapted):

5.写一个简单的.proto文件

6.看看生成的文件中为我们生成了哪些方法

三、使用protpbuf生成的方法

总结


前言

在网络的学习中,我们知道了如果想要进行跨网络通信就必须要定义“协议”,而“协议”可以帮助网络通信的两台主机解析数据,进而实现通信的效果。网路通信的方式有很多,但是都离不开一件事,那就是对数据进行序列化和反序列化。而我们常常听到的Json就是序列化工具的一种,本文要介绍的是另一种由Google开发的一种序列化工具。


一、protobuf的简介

当我们自己手写序列化和反序列化程序的时候,我们常常要做一些比较耗时但没有什么技术含量的工作,比如对一个结构体中的数据赋值、清空等函数的编写。protobuf工具为我们省去了这一过程,我们只需要编写一个后缀名位proto文件指定各个消息的关系即可(protobuf以消息为序列化单位),,而后protobuf会为我们生成两个后缀名分别为pb.cc和pb.h的文件,这两个文件中就包含了一些常见的操作,比如说对数据进行赋值或清空等。而后我们就可以使用这些接口来编写我们的主要代码逻辑了。

图1        protobuf各文件的关系

二、编写一个.proto文件

1.选择使用的protobuf版本

在创建好一个后缀名为.proto的文件后我们要注意的第一个点就是,要在除去注释的第一行指明使用的protobuf版本,如果不对版本进行指明,那么编译器将自动使用“proto2”。

syntax="proto3"

2.指定命名空间(package)

在实现一个项目的时候,我们要对每个“消息”的作用域进行一个规定,也是为了我们代码中减少冲突而必要的一个操作。我们通常使用package声明符进行声明。

3.定义一个“消息”(message)

无论是在网络传输还是在数据持久化存储中,我们都会将数据进行结构化。结构化的数据一方面是为了描述一件复杂的事物(比如说一个“人”往往有多个属性,单一属性是难以描述的)所必需的,另一方面,结构化的数据更方便管理和传输。(在传输和存储的时候,如果数据不以结构化来表示,而是以零散的内置类型来表示,那么当数据丢失时,是较难发现的)。

message 消息名称
{
    //数据....
}

4.定义消息字段

标量类型:

图2        protobuf中的字段类型

注:变成编码指的是:protobuf编码后,该数据类型修饰的数据可能大小变为其他字节数。(当数据用较少字节就能表示的时候,就变小,如果当前数据使用当前字节数不能保存,那么就有可能变大)。

这里还要额外说明几个类型:

这几个类型只做文字说明,后续代码中有体现,这里就不进行代码示例了

枚举类型(enum):

就像C语言中的枚举类型一样,可以用大写字母代之常量,在protobuf中需要注意的是:

①零值常量必须存在且应为枚举中的第一个元素,这是为了兼容proto2的语义

②枚举常量可以嵌套定义

③枚举常量的值应该在32为整数范围内,同时由于①和编码限制负数无效

多选一类型(oneof):

oneof结构中的数据只有一个会被选中,如果多次对该结构变量进行数据输入,以最后一次输入为准。

①该结构中的变量编号不能与已有编号重复

②不能在该结构中使用reapted字段

③多次输入取最后一次输入作为有效输入,并将结构中的其他数据清空

映射类型(map):

map<key,value>

①key是除float和bytes以外的任意标量类型,value可以是任意类型

②map字段不可以用reapted字段修饰

③map中的数据是无序的,但key不可以重复 

泛型类型(Any):

可以在/usr/local/protobuf/include/google/protobuf/该路径下查看所有可定义的类型。

注意:为了避免影响观感该类型将于reapted一同在最后单独演示

数组(reapted):

注意:为了避免影响观感该类型将于reapted一同在最后单独演示

5.写一个简单的.proto文件

syntax="proto3";
package Person;

//性别枚举
enum Gender
{
    MAN=0;
    WOMAN=1;
    SECRECY=2;
}

//定义一个“人信息”消息
message PersonInfo
{
    int32 age=1;
    string ID=3;
    Gender sex=4;
    double height=5;

    //oneof类型
    oneof contact_information
    {
        string qq=8;
        string wechat=9;
        string email=10;
    }
    
    //map类型
    map<string,string> ramark=2;
}

我们编写完该文件之后,我们可以在终端中输入该命令来使用该规则生成.pb.cc和.pb.h文件

protoc --cpp_out=. person.proto
图3        protoc解释
图4        使用protobuf工具生成的文件

6.看看生成的文件中为我们生成了哪些方法

我们点解生成文件中的.h文件

图5        查看生成的.h文件

如果你不喜欢手动滑翻查找所需要的信息,可以使用组合键ctrl+f来打开搜索框,将对应的搜索内容输入到搜索框中查找即可,这里要注意的是如果你要使用组合键查找某一字段的方法最好将搜索框中的内容写为:

[定义的变量][空格]=[空格][变量对应的编号]

图6        使用组合键查找生成的头文件中的方法

三、使用protpbuf生成的方法

请注意:本阶段只对语法进行解析,故不作错误处理。最后在编写一个项目的时候会对错误处理进行添加,在项目中不对可能的错误处理是一个很不好的选择。

#include <iostream>
#include <string>
#include <fstream>
#include "person.pb.h"
using namespace std;


void printperson(Person::PersonInfo& tmp)
{
    cout<<"age: "<<tmp.age()<<endl;
    cout<<"ID: "<<tmp.id()<<endl;
    cout<<"sex: "<<tmp.sex()<<endl;
    cout<<"height: "<<tmp.height()<<endl;
    cout<<"qq: "<<tmp.qq()<<endl;//这里应该做特殊判断,但是我们已经知道到底传入了那个联系方式,这里就不做判断了
    
    for(const auto &e:tmp.ramark())
    {
        cout<<"key: "<<e.first<<"value: "<<e.second<<endl;
    }
}

int main()
{
    //向消息中写入数据
    Person::PersonInfo personin;
    personin.set_age(21);
    personin.set_id("10086");
    personin.set_sex(Person::Gender::SECRECY);
    personin.set_height(170.8);
    personin.set_qq("10089");
    personin.mutable_ramark()->insert({"hello","world"});

    //向二进制文件中写入数据
    fstream write("person.bin",ios::out|ios::trunc|ios::binary);
    personin.SerializeToOstream(&write);
    write.close();

    //从二进制文件中读取数据
    fstream read("person.bin",ios::in|ios::binary);
    Person::PersonInfo personout;
    personout.ParseFromIstream(&read);

    printperson(personout);

    read.close();
    return 0;
}

图7        生成的二进制文件与运行结果

解释:protobuf生成的给变量赋值的方法通常是set_xxx,但是在对map赋值的时候我们使用的是mutable_xxx这个接口的意思是为我们开辟这样一份map空间供我们使用。


总结

本文讲解了一些与protobuf有关的简单操作,下一篇文章将对其他的一些字段与protobuf在网络中如何使用进行介绍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2098011.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论文速读|I-CTRL:通过受限强化学习使人型机器人模仿和控制

论文地址&#xff1a;https://arxiv.org/pdf/2405.08726 I-CTRL&#xff08;Imitation to Control Humanoid Robots Through Constrained Reinforcement Learning&#xff09;是一个旨在解决现有人类运动到人型机器人的转换方法在物理可行性上的不足的框架。该框架通过在非物理…

基础闯关3

一、基础任务 大模型在浮点数大小比较上表现不佳&#xff0c;直接询问大模型浮点数大小往往会出现错误&#xff0c;而通过设定适当的提示词可以引导大模型生成正确的答案。提示工程是指设计和优化输入提示&#xff08;prompts&#xff09;的过程&#xff0c;这些提示用于指导大…

一网统管政企联动:计讯构建城市生命线安全智能体的应急管理革新

城市生命线国家政策推动生命线风险频发 随着城市化进程加速&#xff0c;城市安全问题日益凸显&#xff0c;包括自然灾害、建筑老化、环境污染和公共卫生事件等潜在风险。城市不仅要更新“硬设施”&#xff0c;更在于通过大数据、云计算、5G等新兴技术提升城市管理的“软实力”。…

three.js 开发粒子系统

在 three.js 中开发粒子系统&#xff0c;你通常会使用 THREE.Points 和 THREE.PointsMaterial。这些组件允许你创建一个由大量点组成的系统&#xff0c;每个点都可以代表一个粒子&#xff0c;并可以自定义其大小、颜色、透明度等属性。以下是一个基本的步骤指南&#xff0c;用于…

赞奇科技与华为云共襄828 B2B企业节,激活数字内容“云”创作

8月28日&#xff0c;在2024中国国际大数据产业博览会上&#xff0c;第三届828 B2B企业节正式开幕&#xff0c;旨在融通数智供需&#xff0c;加速企业智改数转&#xff0c;助推中国数智产业实力再升级。 828 B2B企业节是全国首个基于数字化赋能的企业节&#xff0c;由华为联合上…

kafka安装配置、以及遇到闪退问题的解决办法

一、Kafka对于zookeeper是强依赖&#xff0c;保存kafka相关的节点数据&#xff0c;所以安装Kafka之前必须先安装 zookeeper 详细安装过程参见这位大神写的博客 windows系统kafka小白入门篇——下载安装&#xff0c;环境配置&#xff0c;入门代码书写_windows kafka-CSDN博客 注…

【C++11及其特性】智能指针——unique_ptr

unique_ptr目录 一.排他所有权模式二.auto_ptr的缺点1.可以直接复制和拷贝构造2.STL可以直接赋值3.不支持动态内存分配数组 三.unique_ptr(C11)1.不支持直接赋值和构造2.STL可以不可以直接赋值3.支持动态内存分配数组 四.unique_ptr的用法1.构造函数2.赋值操作3.主动释放对象4.…

免费的电脑录屏软件,这几款软件满足录屏需求!

在数字化时代&#xff0c;电脑录屏已成为我们日常生活和工作中不可或缺的一部分。无论是教学演示、游戏直播、会议记录&#xff0c;还是视频创作&#xff0c;一款优秀的录屏软件都是不可或缺的。今天&#xff0c;就为大家推荐几款免费、高效、易用的电脑录屏软件&#xff0c;帮…

首批国自然博士项目获批名单

【SciencePub学术】从公开新闻来看&#xff0c;已经有20所高校的博士生获批项目&#xff0c;分别是北京大学、清华大学、北京航空航天大学、东南大学、复旦大学、华中科技大学、吉林大学、兰州大学、南方科技大学、南开大学、山东大学、上海交通大学、四川大学、武汉大学、南京…

VSCode必备插件!快看过来!

同学同学&#xff0c;你是不是也很头疼VSCode不知道安装什么插件啊&#xff1f;尤其是萌新小白&#xff0c;更是一头雾水&#xff0c;那就快来一起看看吧~我帮你整理了一些非常实用的插件&#xff0c;安装上它们&#xff0c;你的开发体验会大大提升&#xff01; 1. Chinese (S…

DWG如何转换成PDF?总结了四种转换

DWG如何转换成PDF&#xff1f;在日常工作和学习中&#xff0c;经常需要将CAD软件中的DWG文件转换为PDF格式&#xff0c;以便于更广泛地分享和查阅。那么具体要怎么做&#xff0c;才能实现两种格式的顺利转换呢&#xff1f;为了帮助读者轻松完成这一任务&#xff0c;本文将详细介…

网络价格管控行动:四大策略,打击低价

网络价格管控的举措 设定最低售价约束&#xff1a;品牌方能够与在线零售商订立协议&#xff0c;清晰界定产品的最低售价&#xff0c;以守护品牌形象与市场秩序。推行动态定价策略&#xff1a;依照市场需求、竞争态势以及库存状况动态调节产品价格&#xff0c;保障市场竞争力并…

Java爬虫开发:Jsoup库在图片URL提取中的实战应用

在当今的互联网时代&#xff0c;数据的获取和处理变得尤为重要。对于网站内容的自动化抓取&#xff0c;爬虫技术扮演着不可或缺的角色。Java作为一种广泛使用的编程语言&#xff0c;拥有丰富的库支持网络爬虫的开发。其中&#xff0c;Jsoup库以其简洁、高效的特点&#xff0c;成…

51单片机 - 定时器0(按键控制LED流水灯模式)

时间&#xff1a;2024.9.2 目的&#xff1a;手撕51 作者&#xff1a;Whappy 定时器0寄存器配置 1.定时器0配置过程 首先要配置定时器的寄存器TCON和TMOD使计数器开始计数及定时器的初始值&#xff0c;配置使这个链路连起来。 #include <REGX52.H>void Timer0_Init() {…

【HarmonyOS 4.0】鸿蒙应用模型

应用模型是HarmonyOS为开发者提供的应用程序所需能力的抽象提炼&#xff0c;它提供了应用程序必备的组件和运行机制。有了应用模型&#xff0c;开发者可以基于一套统一的模型进行应用开发&#xff0c;使应用开发更简单、高效。随着系统的演进发展&#xff0c;HarmonyOS先后提供…

java 实现文本转音频

文章目录 一、前言二、实现流程2.1 下载jacob-1.18.zip2.2 拷贝jacob-1.18-x64.dll2.3 pom 添加依赖2.4 代码实现 一、前言 本文基于Windows自带的SAPI.SpVoice&#xff0c;通过java代码实现文本转语音的功能。 二、实现流程 2.1 下载jacob-1.18.zip 链接&#xff1a;https…

红帽认证初级有用吗?对个人帮助,报名时间分享

红帽认证初级即红帽认证系统管理员&#xff08;RHCSA&#xff09;是有用的。 拥有 RHCSA 认证的管理员掌握了 Linux 操作系统的基本知识和技能&#xff0c;能够准确理解和解决系统操作中的各种问题。他们了解并熟悉 Linux 命令行和 GUI 界面&#xff0c;可以高效地完成各种任务…

OpenCV绘图函数(15)图像上绘制矩形函数 rectangle()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 绘制一个简单的、粗的或填充的直立矩形。 这个函数 cv::rectangle 绘制一个矩形轮廓或一个填充的矩形&#xff0c;其两个相对的顶点分别是 pt1 和…

大数据-114 Flink DataStreamAPI 程序输入源 自定义输入源 Rich并行源 RichParallelSourceFunction

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

(五)vForm 动态表单文件上传、下载

系列文章目录 (一)vForm 动态表单设计器之使用 (二)vForm 动态表单设计器之下拉、选择 (三)vForm 动态表单解决下拉框无数据显示id问题 (四)vForm 动态表单自定义组件、属性 目录 系列文章目录 前言 一、文件上传 1.前端 2.后端 二、文件下载 1.前端 2.后端 总结 …