Proto协议详解

Protobuf(Protocol Buffers)是由Google公司开发的一套数据序列化协议,是一种轻便高效的结构化数据存储格式,可用于数据存储、通信协议等领域。

一、Proto协议简介

Proto协议是一种语言无关、平台无关、可扩展的数据序列化协议。

和XML、JSON等协议相比,Proto协议具有更高的效率,更小的消息体大小。相对于XML和JSON,Proto的解析速度大约快2~3倍,序列化后的消息体大小仅为JSON的1/3左右,XML的1/10左右。

Proto协议的优点在于其灵活性。在不更改协议的情况下,可以向现有消息添加新的属性,添加新的消息类型和子Message。

二、Proto协议的消息定义

Proto协议的消息定义基于.proto文件来描述消息。.proto文件是一个文本文件,包含了消息名、字段名、数据类型描述。

例如:

syntax = "proto3";
package my_package;
message Person {
  string name = 1;
  int32 age = 2;
  bool married = 3;
}

上述代码定义了一个名为Person的消息类型,包含了3个字段:name、age和married。其中各个字段的含义分别是:

  • name的类型是string,字段编号为1;
  • age的类型是int32,字段编号为2;
  • married的类型是bool,字段编号为3

三、Proto协议的数据类型

Proto协议支持的数据类型有基础数据类型、枚举类型和Message类型。

基础类型包括:

  • double
  • float
  • int32、int64、uint32、uint64、sint32、sint64、fixed32、fixed64、sfixed32、sfixed64
  • bool
  • string
  • bytes

枚举类型需要在.proto文件中单独声明,通过enum关键字指定,例如:

enum Color {
  RED = 0;
  BLUE = 1;
  GREEN = 2;
}

Message类型可以嵌套使用,例如一个Person对象中嵌套一个Address对象:

message Person {
  string name = 1;
  int32 age = 2;
  Address address = 3;
}
message Address {
  string street = 1;
  string city = 2;
  string state = 3;
  string zip_code = 4;
}

四、Proto协议的序列化和反序列化

Proto协议支持将消息体序列化为二进制数据流,以及将二进制数据流反序列化为消息体。

在序列化时,可以使用protobuf提供的SerializeToString()方法将消息序列化为字符串,也可以使用SerializeToOstream()方法将消息序列化为流。反序列化时,可以使用ParseFromString()方法将字符串解析为消息,也可以使用ParseFromIstream()方法将流解析为消息。

下面是序列化和反序列化的示例代码:

#include 
#include 
#include "example.pb.h"
using namespace std;
int main() {
  // 创建一个Person对象
  Person person;
  person.set_name("张三");
  person.set_age(20);
  person.set_married(false);
  Address *address = person.mutable_address();
  address->set_street("XX路");
  address->set_city("XX市");
  address->set_state("XX省");
  address->set_zip_code("000000");
  // 将Person对象序列化为字符串
  string str;
  person.SerializeToString(&str);
  cout << "序列化后的字符串:" << str << endl;
  // 将字符串反序列化为Person对象
  Person new_person;
  new_person.ParseFromString(str);
  cout << "反序列化后的Person对象:" << endl;
  cout << "name:" << new_person.name() << endl;
  cout << "age:" << new_person.age() << endl;
  cout << "married:" << new_person.married() << endl;
  Address new_address = new_person.address();
  cout << "address:" << endl;
  cout << "street:" << new_address.street() << endl;
  cout << "city:" << new_address.city() << endl;
  cout << "state:" << new_address.state() << endl;
  cout << "zip_code:" << new_address.zip_code() << endl;
  return 0;
}

五、Proto协议的使用场景

Proto协议通常用于网络通讯领域中的数据传输和RPC调用。在网络通讯中,使用Proto协议能够有效地降低消息的体积和网络开销,提高传输效率。

RPC调用是一种进程间通讯(IPC)的方式,Proto协议用于定义RPC调用的请求和响应消息格式,以及进行序列化和反序列化操作。

六、Proto协议的其他特点

Proto协议还具有以下几个特点:

  • 支持向前和向后兼容,即可以在不改变原有消息格式的情况下,添加或删除字段;
  • 支持多种语言进行消息定义及实现,包括C++、Java、Python等;
  • 具有较好的扩展性和可靠性,支持高并发情况下的数据传输。

七、结语

Proto协议是一种高效、可扩展、可靠的数据序列化协议,具有广泛的使用场景。熟练掌握Proto协议的使用,对于开发高可靠、高效的网络通讯和RPC调用应用具有重要的意义。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/151082.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-11-10 01:12
下一篇 2024-11-10 01:12

相关推荐

  • 机智云gagent属于哪个协议?

    机智云gagent主要是基于MQTT协议,同时支持TCP、TLS、WebSocket等多种协议。 一、MQTT协议介绍 MQTT全称Message Queuing Telemetr…

    编程 2025-04-29
  • 使用Netzob进行网络协议分析

    Netzob是一款开源的网络协议分析工具。它提供了一套完整的协议分析框架,可以支持多种数据格式的解析和可视化,方便用户对协议数据进行分析和定制。本文将从多个方面对Netzob进行详…

    编程 2025-04-29
  • 如何取消火车票自动抢票协议

    火车票自动抢票协议,是一种利用技术手段在系统繁忙的情况下,自动刷取并抢购火车票的行为。虽然在某些情况下能够提高购票成功率,但是也会影响其他乘客的购票权益。因此,取消火车票自动抢票协…

    编程 2025-04-29
  • USB协议栈

    USB(Universal Serial Bus)是一种常见的计算机外部接口,它已经被广泛使用在各种设备中,例如打印机、键盘、鼠标等。在实现USB通信的过程中,USB协议栈起着非常…

    编程 2025-04-27
  • Linux sync详解

    一、sync概述 sync是Linux中一个非常重要的命令,它可以将文件系统缓存中的内容,强制写入磁盘中。在执行sync之前,所有的文件系统更新将不会立即写入磁盘,而是先缓存在内存…

    编程 2025-04-25
  • 神经网络代码详解

    神经网络作为一种人工智能技术,被广泛应用于语音识别、图像识别、自然语言处理等领域。而神经网络的模型编写,离不开代码。本文将从多个方面详细阐述神经网络模型编写的代码技术。 一、神经网…

    编程 2025-04-25
  • nginx与apache应用开发详解

    一、概述 nginx和apache都是常见的web服务器。nginx是一个高性能的反向代理web服务器,将负载均衡和缓存集成在了一起,可以动静分离。apache是一个可扩展的web…

    编程 2025-04-25
  • Python输入输出详解

    一、文件读写 Python中文件的读写操作是必不可少的基本技能之一。读写文件分别使用open()函数中的’r’和’w’参数,读取文件…

    编程 2025-04-25
  • Linux修改文件名命令详解

    在Linux系统中,修改文件名是一个很常见的操作。Linux提供了多种方式来修改文件名,这篇文章将介绍Linux修改文件名的详细操作。 一、mv命令 mv命令是Linux下的常用命…

    编程 2025-04-25
  • git config user.name的详解

    一、为什么要使用git config user.name? git是一个非常流行的分布式版本控制系统,很多程序员都会用到它。在使用git commit提交代码时,需要记录commi…

    编程 2025-04-25

发表回复

登录后才能评论