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