?? tcp粘包問題處理
以上圖的協(xié)議結構,來舉個粟子:
?? 1.我們收到完整的一個協(xié)議串為hex碼為:
232301314731424c35325037545231313535323001000000
?? 2.對應的拆解一下,各項數(shù)值為
列名 | HEX值 |
---|---|
起始符 | 2323 |
命令單元 | 01 |
車輛識別碼 | 314731424c353250375452313135353230 |
數(shù)據(jù)加密方式 | 01 |
數(shù)據(jù)單元長度 | 0000 |
校驗碼 | 00 |
?? 3.而我們收到粘包的時颖御,或者半包的情況是這樣的。
- 3.1 ?? 場景1
一次性接收收到完整的兩個數(shù)據(jù)串:
232301314731424c35325037545231313535323001000000232301314731424c35325037545231313535323001000000
- 3.2 ?? 場景2
第一次只收到半包的數(shù)據(jù)串:
232301314731424c353250375
- 3.2 ?? 場景3
第一次收到一個半的數(shù)據(jù)串:
232301314731424c35325037545231313535323001000000232301314731424c35325037545231
第二次會收到剩余的數(shù)據(jù)串:
313535323001000000
?? 4. 第三點就是我們收到粘包抢呆,半包,大概就這些情況屠橄。
一般處理的方法也很簡單室埋,就通過起始符處理分割一下就可以。這個協(xié)議在定義的時候辜王,就有考慮到了惫企。
? 如:遇到場景1
通過起始符進行分割撕瞧,就可以拆成兩個單獨的包了。
? 如:遇到場景2
包未完整,繼續(xù)等待,阻塞不處理就好.
? 如:遇到場景3
通過起始符進行分割,可以拿到第一個包风范。
再繼續(xù)等待后面的數(shù)據(jù)包過來咨跌,這樣第二個包也就完整了沪么。
? 這種具體代碼中處理的時候硼婿,流程大概是這樣:
前提補充一下:
一般我們設計系統(tǒng)時,線程分為兩部分
一部分用于專門處理接收處理.(這部分的線程數(shù)量一般設置為CPU核心數(shù)的兩倍.).下文稱收包線程
一部分用于專門處理解析處相關業(yè)務處理..下文稱業(yè)務線程
4.1 "收包線程"-->讀取流的數(shù)據(jù)串,
4.2 "收包線程"-->檢查數(shù)據(jù)串格式
4.3 "收包線程"-->如果滿足一個整包禽车,"收包線程"就丟給"業(yè)務線程"去處理.
4.4 "收包線程"-->如果不滿足,將讀標重置為讀取之前就好.
(每次也要注意去檢索一下緩沖區(qū)寇漫,以防垃圾包太多過來讓緩沖區(qū)爆了,程序掛了)