TCP粘包和拆包

Tcp是個(gè)“流協(xié)議”,所謂流,就是沒有界限的一連串?dāng)?shù)據(jù),沒有界限。TCP底層不了解業(yè)務(wù)數(shù)據(jù)的含義,它會(huì)根據(jù)TCP緩沖區(qū)的實(shí)際情況進(jìn)行包的劃分,所以業(yè)務(wù)上認(rèn)為,一個(gè)完整的包可能被TCP拆分為多個(gè)包進(jìn)行發(fā)送,也可能把多個(gè)小包封裝成一個(gè)大的數(shù)據(jù)包進(jìn)行發(fā)送,這就是所謂的TCP粘包和拆包問題。

粘包/拆包問題說明

image

假設(shè)客戶端分別發(fā)送了兩個(gè)數(shù)據(jù)包,D1和D2給服務(wù)端,由于服務(wù)端一次讀取到的字節(jié)數(shù)是不確定的,故可能存在以下情況:

  • 服務(wù)端分別收到了D1和D2,沒有粘包和拆包

  • 服務(wù)端一次性收到了D1和D2,稱為TCP粘包

  • 服務(wù)端兩次讀取到了兩個(gè)數(shù)據(jù)包,第一次讀到了D1的完整部分和D2的部分?jǐn)?shù)據(jù),第二次讀到了D2的剩余部分。 這稱為TCP拆包

  • 服務(wù)端兩次讀取到兩個(gè)數(shù)據(jù)包,第一次是D1的部分,第二次是D1的剩余部分和D2的完整部分

也有可能D1和D2非常大,期間發(fā)生多次拆包。

粘包/拆包原因

  • 應(yīng)用程序write寫入的字節(jié)大小大于套接口緩沖區(qū)的大小
  • 進(jìn)行MSS大小的TCP分段
  • 以太網(wǎng)幀的payload大于MTU進(jìn)行IP分片
image

粘包問題解決方案

由于底層無法理解上層的業(yè)務(wù)數(shù)據(jù),所以底層是無法保證數(shù)據(jù)不被拆分和重組的。只能通過設(shè)計(jì)上層的協(xié)議棧來解決,業(yè)界的方案可歸納如下:

  • 消息定長(zhǎng),例如每個(gè)報(bào)文固定200字節(jié),如果不夠,空位補(bǔ)空格
  • 在包尾增加回車換行符進(jìn)行分割,如FTP協(xié)議
  • 將消息分為消息頭和消息體,消息頭中包含消息的長(zhǎng)度,字段等信息
  • 更復(fù)雜的應(yīng)用層協(xié)議

最后

在學(xué)習(xí)Netty,這里摘抄《Netty權(quán)威指南》

參考

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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