Proto3序列化協議

2021-10-24 19:46:25 字數 1273 閱讀 7257

對於網際網路應用來說,客戶端-客戶端、客戶端-服務端之間需要資料的互動,其資料傳輸是二進位製流的方式在網際網路上傳輸,因為需要一種手段將資料物件編碼為一種可以在網路上傳輸的二進位製流,這個過程就叫做序列化。同樣的,客戶端在收到二進位製流需要解碼出資料,這個過程叫反序列。

簡單理解就是序列化就是按照某種編碼方式將資料轉換為二進位製流以方便在網路上傳輸,同時這種編碼方式是可逆的和可理解的。

按照上述定義不難理解,json也是一種序列化的一種方式,將物件編碼為字串(二進位制)進行傳輸。

同樣的proto3是google推出的一種序列化框架。全稱是protocol buffers。

其具有以下特點:

我們定義了乙個person的訊息型別,那protobuf是怎麼把它編碼成二進位制的呢?其實它是把message轉成一系列的key-value,key就是欄位號,value就是字段值,大概這樣子存:

message person
=1,=2稱為tag, 唯一標識每個元素,其值不可重複,其中tag在1-15之間編碼為乙個位元組,大於15位元組將需要多個位元組進行編碼,因此作為優化手段,1-15 tag多使用者經常出現的元素,15+的tag用於不長出現或者可選的元素,此外,對於repeated型別的message,其每個元素都需要乙個tag,所以repeated適合用小於15的tag。

對於上述的定義,其會按照[tag1][value1][tag2][value2][tag3][value3]...的方式進行編碼,

解碼時,會從左往右解析每乙個key-value,假如遇到某個key-value無法解析了,那麼就直接跳過,不會影響到其它key-value的解析,因此如果你加了新字段,生成位元組流,然後用舊版本解析,這時它還是能夠解析出舊版本的字段的,新字段只是被忽略而已,這就是protobuf的向後相容。

需要注意,一旦發布proto協議,其tag值就不能修改,新增字段只能使用未使用的tag(即使刪除的tag也不可以),刪除乙個字段可以,解碼時如果沒有該字段會預設填充預設值,如果刪除刪除乙個字段,最好採用reversed標識使用過的tag值,避免後續誤使用舊的tag值。

message songservicerequest
//型別是大寫+駝峰式

enum foobar

//駝峰+大寫

service fooservice

python3 序列化物件和反序列化物件

def store data,filename 序列化,寫到本地磁碟檔案 import pickle with open filename,wb as f pickle.dump data,f def grab filename 反序列化,從本地檔案讀出原有的物件 import pickle wit...

A08 序列化與反序列化

using system using system.collections.generic using system.linq using system.text using system.threading.tasks namespace a01 serializeanddeserialize s...

C 語言 08 序列化與反序列化

a.序列化 是將物件的狀態儲存到特定儲存介質中的過程 i.語法 public void serialize 序列化過程的檔案流,儲存的物件 b.返序列化 是從特定儲存介質中將資料重新構建物件的過程 i.語法 public object deserialize 檔案流 i.注意 deserialize...