粘包/拆包問題一直都存在,只是到TCP就拆不動了。

  • OSI open-system-Interconnection
  • TCP/IP 5層協議棧
    • 應用層和操作系統的邊界是 系統調用 ,對應到網絡編程是socket api
  • TCP/UDP 概況
  • TCP粘包問題
  • TCP/IP報頭深思

OSI開放系統互聯

定義了網絡框架,以層爲單位實現協議,同時控制權逐層傳遞。

OSI實際並沒有落地,TCP/IP 5層協議棧是目前主流的落地實現

TCP/IP 5層協議棧

TCP/IP協議棧不止是傳輸層tcp/網絡層ip, 還包括應用層等,這是一個協議簇,只是因爲TCP/IP很具代表性。

不管是OSI還是TCP/IP5層協議棧,均會出現應用程序和操作系統邊界(代碼執行在用戶態/內核態)。

邊界調用被稱爲系統調用system callsocket api便是TCP/IP協議棧中應用層的網絡編程接口。

TCP/UDP概覽

  • TCP: Transmission Control Protocol面向連接的,可靠的,基於字節的、雙向流式傳輸層協議。

  • UDP: USer Datagram Protocol面向消息的傳輸服務,傳輸的數據是有邊界的。
    區別:

TCP可靠性是tcp三次握手的基礎,在此之上,增加了seq、ack數據確認機制、 擁塞控制, 其中ack= seq+len(data)。

UDP: 想法就發,不用三次握手建立連接。

我們目前常見的應用場景底層都是tcp,比如http請求、sql數據庫請求。

建立TCP連接之後,才能做http請求、sql請求,tcp連接很耗時,故服務器都存在連接池化機制。

這裏我要給自己強調的是:開發者對於tcp一定不要帶入http請求-響應模型,tcp是雙向通信流。

TCP粘包/拆包

TCP粘包並不是TCP協議造成的問題,因爲tcp協議本就規定字節流式傳輸

  • 正常的理想情況,應用層下發的兩個原始包恰好滿足TCP緩衝區的大小或達到TCP等待時長,分別發送兩個包;
  • 粘包:兩個包較小,間隔時間短,發生粘包,合併成一個包發送;
  • 拆包:一個包過大,超過緩存區大小,拆分成兩個或多個包發送;
  • 拆包和粘包:Packet1過大,進行了拆包處理,而拆出去的一部分又與Packet2進行粘包處理。

image.png

粘包拆包問題在數據鏈路層、網絡層以及傳輸層都有可能發生。
數據鏈路層,網絡層的粘包和拆包問題都由協議自行處理了,我們日常的網絡應用開發都在對接傳輸層,故面臨的粘包問題指的是TCP粘包。


當粘包、拆到TCP層的時候我們就沒辦法識別應用層的請求/調用了, 所以解決方法是:一開始就需要在字節流中加入[特殊分隔符]或者[長度+偏移量]含義。

HTTP 超文本傳輸協議的規定如下:

image.png

旁白

梳理了整個TCP/IP協議棧各層封包邏輯, 我們就知道粘包、拆包一直都存在,只是拆到TCP層的時候,我們沒有辦法區分應用層斷續發送的請求/調用, 這就是我們口口相傳的TCP粘包/拆包問題, 需要應用層用特殊分隔符或者長度解析。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章