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/zh-hant/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

發表回復

登錄後才能評論