- 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 call, socket 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進行粘包處理。
粘包拆包問題在資料鏈路層、網路層以及傳輸層都有可能發生。
資料鏈路層,網路層的粘包和拆包問題都由協議自行處理了,我們日常的網路應用開發都在對接傳輸層,故面臨的粘包問題指的是TCP粘包。
當粘包、拆到TCP層的時候我們就沒辦法識別應用層的請求/呼叫了, 所以解決方法是:一開始就需要在位元組流中加入[特殊分隔符]或者[長度+偏移量]含義。
HTTP 超文字傳輸協議的規定如下:
旁白
梳理了整個TCP/IP協議棧各層封包邏輯, 我們就知道粘包、拆包一直都存在,只是拆到TCP層的時候,我們沒有辦法區分應用層斷續傳送的請求/呼叫, 這就是我們口口相傳的TCP粘包/拆包問題, 需要應用層用特殊分隔符或者長度解析。