TLV-簡單的資料傳輸協議
有段時間沒有寫部落格了,這段期間要說也夠忙的(其實也沒忙到哪去),從3月底到5月初這段期間一直在找暑期實習,幸運的是自己算是找到了自己希望的,從開始糾結TX,到後來確定,以及又拿到阿里的實習機會,這段過程真是夠虐心的。不過自己還是選擇了深圳,也許是阿里巴巴的通知有點晚,也許是自己覺得毀約去杭州有點不好,也許是因為那個QQ空間上裝逼的我讓我做了這個感性的決定.不管怎樣,感謝阿里巴巴給的機會,也特別感謝六一、淘寶褚霸兩位阿里大牛沒有狠狠虐我。不多說,就以上做一個小結吧。(最近總是喜歡囉嗦)
不扯淡,今天要說的便是TLV,即Tag(Type)-Length-Value,是一中簡單實用的資料傳輸方案。在TLV
其實就是一個簡單的自定義通訊協議,將對應的資料進行編碼、組織。我們之前自己寫一個簡單的C/S模型資料傳輸時,比如傳送一個非基礎型別的結點資訊,就會採用struct,比如:
struct Messagebase{
unsigned int command;
char login_code[8];
char name[8];
};
這個struct描述了簡單的login操作的需求資訊,但是比如說有一天我們需要增加一個欄位,加上
struct Messagebase{
unsigned int command;
unsigned int birthday;
char login_code[8];
char name[8];
};
這樣導致的結果就是對應解析的程式碼也需要進行修改,加入針對birthday欄位的處理,因為原先的處理不知道資料包的第三個欄位是name還是login_code,這樣的處理只能用作簡單的資料包擴充套件。
但是這個擴充套件有很大的侷限性,總不能這麼一直修改吧,所以考慮可以給每個資料段加上一個表示Tag
struct tlv_entity {
unsigned char* tag; //標記
unsigned char* length; //資料長度
unsigned char* value; //資料
unsigned int tagSize; //標記佔用位元組數
unsigned int lengthSize; //資料長度佔用位元組數
tlv_entity* sub_tlventity; //子巢狀TLV實體
};
資料的傳送過程其實就是打包的過程,目的是將一個從終端上發的請求資料——位元組陣列,構造成一系列的TLV結構實體;解包的目的剛好相反,就是將TLV結構實體解析成位元組陣列,所以對應我們需要一個針對TLV資料的封裝處理:
class tlv_deal{
Public:
tlv_deal();
virtual ~tlv_deal();
static void construct_MS(unsigned char* buffer,unsigned int buffer_len,
tlv_entity* entity,unsigned int entity_len,unsigned int status=0 );
static void parse_MS(unsigned char* buffer,unsigned int buffer_len,
tlv_entity* entity,unsigned int entity_len);
};
對於簡單的TLV資料元結構,盜圖如下:
複合的TLV資料元結構:
Primitive or constructed BER-TLV data object number,包含一個簡單資料元結構或者也可以是一個符合資料元結構。這樣可以看出,演算法中必須要實現Tag的巢狀功 能,遞迴演算法不可少。
其實說白了,我們看到的XML等標記式的結構也是屬於TLV的,以及facebook的thrift,還有google的protobuf (在這說純屬裝逼,只是簡單瞭解),基本都是TLV的例子,但是模型簡單,實際的需求決定了處理的難度。哎,就算是簡單的概念吧,我估計大家都沒發覺自己以前寫程式碼用了這樣的概念,只是不知道名字罷了,但是真正的一個巢狀式的TLV結構,在實際應用中絕對還是不簡單的,打包、解析也絕對會是體力活。額,都不知道說什麼了,還是去再看看對應的應用層協議設計再來裝逼吧。