常用的某協議設計如下: 包括幀頭,命令字,幀序號,幀長度,幀數據,校驗字,幀尾。
1B |
1B |
2B |
4B |
NB |
2B |
2B |
幀頭 |
命令字 |
幀序號 |
幀長度 |
幀數據 |
校驗字 |
幀尾 |
HEAD |
CMD |
FRAME_SEQ |
DATA_LEN |
DATA |
CRC |
TAIL |
一般協議解析時,定位到幀頭,通過幀長度汲取一個幀。然后校驗下校驗字和幀尾確保本幀沒問題。
然后這樣設計有一個小風險,就是幀數據也包含幀頭就很尷尬。
1、讀取到錯誤的幀長度有內存溢出風險。
2、讀取到錯誤的幀長度導致后續的幀都被誤讀取。
3、本幀必然發生校驗字錯誤被丟棄。
因此,最好能對幀數據進行幀頭的剔除工作。
今天翻看tcp/ip看到一節,SLIP的協議包裝可以借鑒下。
如圖,每段IP數據段被封裝時,有個END標記“0xC0“,對數據報中的“0xC0”進行加工,翻譯成“0xdb0xdc”,再對報文中的"0xdb"后面加上“0xdd”。
這樣只有在數據包的首尾才有“0xC0”了。
缺點就是1、報文稍稍變長幾個字節,稍微影響點帶寬(取決於保衛中關鍵字的出現頻率)
2、需要對數據報進行逆向翻譯操作,帶來了一定的工作量。
但總體而言還是有意義的吧,總比報文亂序了好。