深入淺出圖解【計算機網絡】 之 【TCP可靠傳輸的實現: 三次握手+滑動窗口】


【前言】這個系列主要會介紹一些計算機網絡體系中“看上去稍有些復雜”但“一旦理解了又會很容易”的內容,我會嘗試通過示意圖/動圖的方式對概念進行盡量直觀的詮釋,如果能夠對大家學習計算機網絡有所啟發的話就最好了。

TCP(Transmission Control Protocol)是整個TCP/IP協議族中為數不多的能扛起“可靠傳輸”大旗的“扛把子”了(上有應用層協議嗷嗷待哺,下有IP協議寄予厚望(注:IP協議是不提供可靠傳輸服務的))能夠肩負如此重任說明它的協議組成一定不簡單,不過,作為一個“協議”,它一定也不會很難理解的。

這部分的內容我打算分為兩個部分講解,本篇文章主要會講解TCP連接的建立和釋放(三次握手+四次握手),以及發送端的滑動窗口一般原理;至於同樣很重要的“擁塞控制”等內容,我會放到下一篇文章中。

說起TCP,我們應該了解它最突出的特點是“基於連接的傳輸”和“以字節為單位(面向字節流)”,這兩點特點與同是運輸層的UDP協議形成了鮮明對比。(UDP不建立連接,以報文為單位,兩者的區別有機會會仔細說說)而實現這兩點也是TCP能夠提供可靠傳輸的關鍵。

預備知識

TCP報文結構

TCP_packet

下面簡單解釋一下報文中一些重要的部分:

  • 源端口和目的端口:各占兩個字節(16位),端口(Port)是運輸層與應用層的服務接口,以實現復用和分用。
  • 序號(sequence number):占4個字節,指本報文段所發送的數據的第一個字節的序號。
  • 確認號(acknowledgement number):同樣占4個字節,是期望收到對方下一個報文段的第一個字節的序號。(即收到對方的報文段最后一個字節的序號加一)
  • (部分)標志位(Flags)
    • 確認(ACK):ACK=1時確認號字段(acknowledgement number)才有效;
    • 同步(SYN):SYN=1表示這是一個“連接請求(SYN)”或“連接接受(SYN-ACK)”報文;
    • 終止(FIN):用於釋放連接,FIN=1表明報文段發送完畢,要求釋放連接。
  • 窗口:占2字節,是用來讓對方設置發送窗口的依據。

面向流的TCP協議

再了解了TCP報文結構之后,我們需要知道,這里的“報文”與我們常見的“報文”有些不同。

TCP 不關心應用進程一次把多長的報文發送到 TCP 緩存。這和UDP的“給多少裝多少”正相反。
TCP 對連續的字節流進行分段,形成 TCP 報文段。
面向字節流

那么分段的依據是什么呢?
TCP在建立連接的基礎上,發送方可以根據對方給出的窗口值(接下來要提到的:使用滑動窗口實現流量控制)和當前網絡擁塞(下一篇文章將要提到的:擁塞控制機制)的程度來決定一個報文段應包含多少個字節(UDP 發送的報文長度是應用進程給出的)。

TCP連接的建立(“三次握手”)與釋放(“四次握手”)

TCP 建立連接的過程叫做“握手”(handshake),可以說是一個頗經典的不那么貼切但為大家所普遍接受的擬人化稱呼。

在連接的建立階段,需要在客戶和服務器之間交換三個 TCP 報文段。稱之為三報文握手(there-way handshake)
3_way_handshake

三報文握手的過程就如上動圖所示,是不是其實很簡單。
就像是兩個隔着很遠的人在測試一個電話線路:
“能聽見我說話嗎?”
“聽見了!能聽見我說話嗎?”
“聽見了!”

與建立連接思路相似的,還有“四報文握手”(four-way handshake)的連接釋放
4_way_handshake

與建立連接不同的是,如果某一方想要釋放連接,另一方“不一定”就想跟着釋放連接,因為它可能還有東西沒傳完呢。
就像是倆人打電話嘮了很久,其中有個人想要睡了:
“喂,我困了,咱明天再聊吧”
“哦哦,那我最后說幾句”
... ...
“好,我說完了,晚安咯”
“晚安”

使用滑動窗口實現可靠傳輸+流量控制

滑動窗口,實際上就是發送方能連續發出的數據(字節流)的閾值。

現在假設,A收到了B發來的確認號為32(表明B期望收到的下一個報文段的開頭序號為32),窗口為20字節的確認報文段,那么A便可以根據這兩個數據構建出如下發送窗口:
發送窗口1

A發送11個字節的數據后,發送窗口位置不變,可用窗口變小:
發送窗口2

此時,B收到了前三個字節,向A發送確認號為35的確認報文字段(同時接收窗口向前移動三個字節);
A的發送窗口在收到B的確認報文后也向前移動三個字節。
發送窗口3

這里,就需要引入“停止等待”和“累計確認”的概念了:
停止等待”,顧名思義,就是每發送完一個分組就停止發送,等待對方的確認。在收到確認后再發送下一個分組。
而在TCP傳輸過程中,為了提高效率、節約資源,采用了“累計確認”的方式:即不必對收到的分組逐個發送確認,而是對按序到達的最后一個分組發送確認,表示到這個分組為止的所有分組都已正確收到了

接着,A繼續向B發送報文,但是B一直沒有發回確認報文。
A在發送至可用窗口為零時便停止發送。
發送窗口4

【后記】
運輸層真的是承上啟下的扛把子,這其中細節還有很多,今天挑了這兩個是因為對於這部分的內容,“直觀上的理解”比“文本上的記憶”更為重要。
TCP的擁塞避免也是個很重要的內容,會出現在下一篇文章中。
最后,你們的反饋就是我最大的動力啦(逃


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM