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-tw/n/151082.html
微信掃一掃
支付寶掃一掃