涉及到通信的地方就會需要通信協定,因為隻有确定了通信協定,通信雙方才能了解對方所發來的資料有什麼含義。BER(Basic Encoding Rule)是一種編碼規格說明,描述如何将ASN.1類型的值編碼成字元串(string of octets)的方法。BER的資料都是由三個域構成:辨別域(Tag)+長度域(Length)+值域(Value),簡稱TLV格式。
1. TLV 簡介
TLV 是一種可變的格式,其中:T 可以了解為 Tag 或 Type ,用于辨別标簽或者編碼格式資訊;
L 定義數值的長度;
V 表示實際的數值。
T 和 L 的長度固定,一般是2或4個位元組,V 的長度由 Length 指定。
2. 位元組序
要正确的解析對方發來的資料除了統一資料格式之外還要統一位元組序。位元組序是指多位元組資料在計算機記憶體中存儲或者網絡傳輸時各位元組的存儲順序。位元組序一般分為大端和小端。
2.1 大端和小端
大端模式(Big-Endian): 高位位元組放在記憶體的低位址端,低位位元組排放在記憶體的高位址端。
小端模式(Little-Endian): 低位位元組放在記憶體的低位址端,高位位元組放在記憶體的高位址端。
下面舉個例子,要把0x1234 存放在 0x2000 位址處,那麼大端模式和小端模式存放方式如下:
2.2 網絡位元組序
網絡位元組順序是TCP/IP中規定好的一種資料表示格式,它與具體的CPU類型、作業系統等無關,進而可以保證資料在不同主機之間傳輸時能夠被正确解釋。網絡位元組順序采用Big-Endian排序方式。
為了進行轉換 bsd socket提供了轉換的函數 有下面四個htons 把unsigned short類型從主機序轉換到網絡序
htonl 把unsigned long類型從主機序轉換到網絡序
ntohs 把unsigned short類型從網絡序轉換到主機序
ntohl 把unsigned long類型從網絡序轉換到主機序
3. 編解碼
假設 Tag(或 Type)和 Length 都是 4位元組表示(unsigned long)。
3.1 編碼步驟使用 htonl 将 Tag(或Type)轉成網絡位元組序,指針偏移 4;
使用 htonl 将 Length 轉成網絡位元組序,指針偏移 4;
若值 Value 為 int、char、short、long 類型,将其轉為網絡位元組序,指針偏移;若值為字元串,寫入後指針偏移 Length;
重複上述三步,繼續編碼後面的 TLV 單元。
3.2 解碼步驟讀取 Tag(或Type)并使用 ntohl 将其轉成主機位元組序,指針偏移4;
讀取 Length ntohl** 将其轉成主機位元組序,指針偏移4;
根據得到的長度讀取 Value,若為 int、char、short、long 類型,将其轉為主機位元組序,指針偏移;若值為字元串,讀取後指針偏移 Length;
重複上述三步,繼續讀取後面的 TLV 單元。
參考連結: