Netty TCP 粘包 & 拆包

粘包/拆包

TCP 的一個(gè)數(shù)據(jù)包可能包含一個(gè)、多個(gè)或者不足一個(gè)應(yīng)用層數(shù)據(jù)包,程序需要按照一整個(gè)應(yīng)用包進(jìn)行處理,這就會(huì)帶來(lái)一個(gè)問(wèn)題,TCP 的數(shù)據(jù)包不能直接拿來(lái)處理。

原因深究

socket 緩沖區(qū):socket 通信時(shí),收發(fā)兩端在內(nèi)核層都有一個(gè)緩沖區(qū),send時(shí),數(shù)據(jù)不會(huì)馬上發(fā)送到對(duì)端,而是寫(xiě)入到send緩沖區(qū),由內(nèi)核在合適的時(shí)機(jī)將數(shù)據(jù)發(fā)送到對(duì)端;接受端原理相似。

MTU(Max Transfer Unit)最大傳輸單元:MTU是網(wǎng)絡(luò)層概念,表示一個(gè)網(wǎng)絡(luò)數(shù)據(jù)幀的最大值,當(dāng)送的數(shù)據(jù)大于MTU時(shí),網(wǎng)絡(luò)層會(huì)對(duì)數(shù)據(jù)進(jìn)行分割發(fā)送,這個(gè)過(guò)程叫做分片

MSS(Max Segment Size)最大分段大小:MSS 是TCP傳輸層的概念,與MTU類似表示TCP數(shù)據(jù)包的最大值。為了達(dá)到最佳的傳輸效能TCP協(xié)議在建立連接的時(shí)候通常要協(xié)商雙方的MSS值,這個(gè)值TCP協(xié)議在實(shí)現(xiàn)的時(shí)候往往用MTU值代替(需要減去IP數(shù)據(jù)包包頭的大小20Bytes和TCP數(shù)據(jù)段的包頭20Bytes)所以往往MSS為1460。TCP根據(jù)MSS 將小數(shù)據(jù)包合并為一個(gè)大的數(shù)據(jù)包,或者將一個(gè)大的數(shù)據(jù)包分割成MSS大小的數(shù)據(jù)包進(jìn)行發(fā)送,這個(gè)過(guò)程叫做分段。TCP 通過(guò) MSS 避免了 在網(wǎng)絡(luò)層的分片。

基于以上,粘包/拆包會(huì)發(fā)生在以下幾種情況:

  1. 單次數(shù)據(jù)寫(xiě)操作超出了socket 緩沖區(qū)的大小,導(dǎo)致內(nèi)核不得不將緩沖區(qū)中的數(shù)據(jù)發(fā)送出去;

  2. 對(duì)于TCP協(xié)議,針對(duì)MSS的數(shù)據(jù)分段;

  3. 以太網(wǎng)幀大于MTU時(shí)的TCP分片;

  4. 應(yīng)用層數(shù)據(jù)包太小導(dǎo)致的數(shù)據(jù)合并;

解決方案

  1. 消息定長(zhǎng),比如規(guī)定一個(gè)數(shù)據(jù)包200bytes,不夠的空格補(bǔ)齊,很明顯這種方式擴(kuò)展性很差;

  2. 采用固定的消息分隔符,通過(guò)分隔符將數(shù)據(jù)包拆解開(kāi);

  3. 數(shù)據(jù)協(xié)議,將數(shù)據(jù)包分為消息頭和消息體,消息頭中說(shuō)明本消息的總長(zhǎng)度;

  4. 其他應(yīng)用層協(xié)議;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容