《計算機網絡傳輸層 TCP協議》


《計算機網絡傳輸層 TCP協議》

1. TCP 協議特點

  • 在 IP 協議之上 ,解決網絡通訊可依賴問題

    • 點對點(不能廣播,多播),面向連接
    • 雙向傳遞 (全雙工)
    • 字節流傳輸:打包成報文段、保證有序接收、重復報文自動丟棄
      • 缺點: 不維護應用報文的邊界(對比HTTP、GRPC)
      • 優點: 不強制要求應用必須離散的創建數據塊、不限制數據塊的大小
    • 流量緩沖: 解決速度不匹配問題
    • 可靠的傳輸服務 (保證可達、丟包時通過重發時延實現可靠性)
    • 擁塞控制
  • 既然TCP是面向連接的,那么如何標識一個連接?

    • 通過TCP的四元組(源地址,源端口,目的地址,目的端口)

      • 所以對於 IPV4 地址,單主機最大TCP連接數為

        \[2^{32+16+32+16} \]

2. TCP協議的任務

  • 主機內的進程尋址(通過端口號)
  • 創建、管理、終止連接
  • 處理並將字節 (8 bit) 流 打包成報文段 ( 如IP報文 )
  • 傳輸數據
  • 保持可靠性與傳輸質量
  • 流量控制與擁塞避免

3. TCP Segment 報文段

每個TCP報文段由固定的20Byte頭部組成,TCP報文頭部 選項可以跟在固定標頭之后。 帶有標頭,使其最多可以標記 65535 個數據字節。

  • 16位源端口號和16位目的端口號。

  • 32位序號:一次TCP通信過程中某一個傳輸方向上的字節流的每個字節的編號,通過這個來確認發送的順序

  • 32位確認號:用來響應TCP報文段,給收到的TCP報文段的序號加1,三握時還要攜帶自己的序號。

  • 4位頭部長度:標識該TCP頭部有多少個4字節,共表示最長15*4=60字節。同IP頭部。

  • 6位保留。6位標志。URG(緊急指針是否有效)ACK(表示確認號是否有效)PSH(提示接收端應用程序應該立即從TCP接收緩沖區讀走數據)RST(表示要求對方重新建立連接)SYN(表示請求建立一個連接)FIN(表示通知對方本端要關閉連接)

  • 16位窗口大小:TCP流量控制的一個手段,用來告訴對端TCP緩沖區還能容納多少字節。

  • 16位校驗和:由發送端填充,接收端對報文段執行CRC算法以檢驗TCP報文段在傳輸中是否損壞。

  • 16位緊急指針:一個正的偏移量,它和序號段的值相加表示最后一個緊急數據的下一字節的序號。

4. TCP 三次握手及狀態變遷

image-20211108155020639

4.1 為什么TCP不能兩次握手進行連接?

​ TCP 連接需要完成兩項工作一是做好發送數據前的准備工作(即雙方都知道對方准備好了) 二是完成序列號(sequence number )的同步,這個序列號在握手的過程中被發送和確認

​ 根據上述如果進行兩次連接 Server 在接收到Client的SYN請求時直接進入到Establishment狀態,並且給Client發送 SYN和ACK 包。但是這個SYN+ACK 包在傳輸的過程中可能丟失,因此Client無法准確的知道Server是否建立起連接。因此Client會忽略Server發送過來數據包,只等連接確認包。而Server在發送數據包分組超時后會重復發送超時的數據包,這樣就造成了死鎖。

​ 上述回答是通過一個博客看到了,但是我從RFC793 [page 32] 文檔看到了如下的說明:

 The principle reason for the three-way handshake is to prevent old duplicate connection initiations from causing confusion.  To deal with this, a special control message, reset, has been devised.  If the receiving TCP is in a  non-synchronized state (i.e., SYN-SENT,SYN-RECEIVED), it returns to LISTEN on receiving an acceptable reset. If the TCP is in one of the synchronized states (ESTABLISHED,FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT), it aborts the connection and informs its user.  We discuss this latter case under "half-open" connections below.

大概意思就是說三次握手是為了防止舊的重復初始化連接造成混亂

client發出的第一個連接請求報文段並沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以后的某個時間才到達server。本來這是一個早已失效的報文段。但server收到此失效的連接請求報文段后,就誤認為是client再次發出的一個新的連接請求。於是就向client發出確認報文段,同意建立連接。假設不采用“三次握手”,那么只要server發出確認,新的連接就建立了。由於現在client並沒有發出建立連接的請求,因此不會理睬server的確認,也不會向server發送數據。但server卻以為新的運輸連接已經建立,並一直等待client發來數據。這樣,server的很多資源就白白浪費掉了。采用“三次握手”的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的確認發出確認。server由於收不到確認,就知道client並沒有要求建立連接。”

4.2 TCP 在Handshake中如果第三次發送包發生了丟失會怎么樣?

  • 服務器角度: 如果第三次ACK確認包丟失。Server的狀態為SYN_REVD ,並根據TCP超時重傳機制,會等待 3秒、6秒、12秒 后重新發送SYN+ACK包,以便Client重新發送ACK包。 而Server重發SYN+ACK包的次數,可以通過設置/proc/sys/net/ipv4/tcp_synack_retries修改,默認值為5.

    如果重發指定次數之后,仍然未收到 client 的ACK應答,那么一段時間后,Server自動關閉這個連接。

  • 客戶端角度:因為客戶端發送完ACK包已經進入了Establishment狀態。客戶端向服務端發送數據,服務端會以RST包進行相應,客戶端就能感知Server的鏈接錯誤了。

5. TCP的可靠傳輸

5.1 TCP的流與報文段

  • 流分段的依據

    • MSS: 防止IP層分段 IP層分段的效率低下

    • 流控制: 控制端的接收能力

  • MSS(Max Segment Size):僅指TCP承載數據,不包含TCP的頭部長度

  • MSS選擇的目的

    • 盡量每個Segment攜帶更多的數據 以減少TCP頭部空間占用率
    • 防止Segment被某個設備的IP層基於MTU拆分
  • 默認 MSS 536字節 (默認MTU 576個字節,20字節IP頭部,20字節TCP頭部)

5.2 TCP是如何實現可靠傳輸的?

  • TCP通過序號機制和重傳機制來實現TCP字節的可靠傳輸的

  • Sequence 序列和 ACK確認號設計目的

    • 跟蹤應用層的發送端數據是否達到

    • 確定接收端有序的接收到字符流

  • 序列號的值針對的是字節而不是報文

5.2.1 序列號存在的問題

在TCP報文頭部序列號(Sequence Number)所占32bit 也就是最多能表達的字節也就是2^32 個也就是4GB,當如果一次TCP連接傳輸的數據超過4G時,在1-4G傳輸過程中,如果數據報傳輸有延遲晚到底,可能會讓接收端分不清那個是先用這個序列號的,那個報文是后用這個序號的

這個也就是PAWS問題(Protect Against Wrapped Sequence numbers )防止序列號回繞

5.3 RTT時間與RTO時間

下圖是RTT的圖示,簡單的來說就是一個報文從發送到接收到響應的時間,但是下面是理想的情況,現實中的計算比這復雜多了

image-20211109011710222

RTO是超時重傳時間,RTO設置應該比RTT略大,如果設置太小,可能數據報已經被ACK了,但是由於超時重發時間設置的太短,就又重發了,重發了本應該不用重發的數據報。如果設置的太大就會導致傳輸的效率太低,如果ACK數據報丟失,需要很長時間來進行重發。

image-20211109011926089

5.4 滑動窗口

image-20211109015542273

6. TCP 擁塞控制

6.1 慢啟動

cwnd: 擁塞窗口大小

rwnd: 接收方窗口大小

慢啟動的思想就是為發送方增加了一個擁塞窗口記為cwnd,擁塞窗口指的是接收到ACK后,發送端還能發送最大的MSS數,發送方的窗口大小 = Min {cwnd,rwnd}。

慢啟動算法就是,每收到一個ACK (eg.也就是經過一個RTT) cwnd的大小*2 ,比如最開始cwnd的大小是 initcwnd,當接收到該報文的ACK ,cwnd的大小就變為initcwnd * 2 。下次發送報文段的數量就是 initcwnd *2 ,再接收到 initcwnd * 2 報文段的ACK后,那么接着發送窗口的大小就是 initcwnd * 4 ,這是一種指數關系

\[CWND = initcwnd * 2^n \]

n 指的是RTT的次數

6.2 擁塞避免

慢啟動閾值:ssthresh

當cwnd<ssthresh時,擁塞窗口使用慢啟動算法,按指數級增長。 當cwnd="">ssthresh時,擁塞窗口使用擁塞避免算法,按線性增長。

擁塞避免算法每經過一個RTT,擁塞窗口增加initcwnd

當到達設置的閾值時發送窗口的大小就每收到一個ACK,cwnd+=initcwnd ,當出現丟包的情況是就立馬將發送窗口的大小設置為 initcwnd.

當發生擁塞的時候(超時或者收到重復ack),RFC5681認為此時ssthresh需要置為沒有被確認包的一半,但是不小於兩個MSS。此外,如果是超時引起的擁塞,則cwnd被置為initcwnd

超時重傳對傳輸性能有嚴重影響。原因之一是在RTO階段不能傳數據,相當於浪費了一段時間;原因之二是擁塞窗口的急劇減小,相當於接下來傳得慢多了。

6.3 快速重傳

有時候擁塞比較輕微,只有少量包丟失,后續的包能夠正常到達。當后續的包到達接收方時,接收方會發現其Seq號比期望的大,所以它每收到一個包就Ack一次期望的Seq號,以此提醒發送方重傳。當發送方收到3個或以上重復確認(Dup Ack)時,就意識到相應的包已經丟了,從而立即重傳它。這個過程稱為快速重傳。

img

為什么要規定湊滿3個呢?這是因為網絡包有時會亂序,亂序的包一樣會觸發重復的Ack,但是為了亂序而重傳沒有必要。由於一般亂序的距離不會相差太大,比如2號包也許會跑到4號包后面,但不太可能跑到6號包后面,所以限定成3個或以上可以在很大程度上避免因亂序而觸發快速重傳。

還有一個問題,如下圖:

img

如果2號和3號包都丟失了,但是后面4,5,6,7號都正常收到了,並觸發了三次ack = 2。在重傳了2號包之后該傳哪個包那,是全部需要重傳還是只傳2號包?

為了解決這種問題,TCP在發送重復的Ack包的時候,會告訴接收方收到的已經收到包的序號,如下圖:

img

這樣發送方就知道該重傳哪個包了,這種方式被稱為選擇性確認(Selective Acknowledgement)

6.4快速恢復

如果在擁塞階段發生了快速重傳就沒有必要像超時重傳那樣處理擁塞窗口了,因為此時的擁塞並不是很嚴重。RFC5681建議此時的慢啟動閾值ssthreh設置為沒有被確認包的1/2,但是不小於2個MSS。擁塞窗口設置為慢啟動閾值加3個MSS。這個過程被稱為快速恢復

7.1 TCP的四次揮手

TCP的四次揮手如下圖所示

image-20211109104744988

7.1 為什么TCP建立連接需要三次握手,而釋放連接需要四次?

當處於Listen狀態的服務器接收到一個SYN報文后,可以將ACK(應答作用)報文和SYN (請求建立連接) 報文放到一個報文中進行發送。

但是在關閉TCP連接時,對方給你發送一個FIN報文,這僅僅表示對方沒有數據給你發送了,但是並不代表你沒有數據給對方發送了。所以先給對方發送一個ACK報文,當發送完數據過后在發送一個FIN報文表示告訴對方你同意關閉連接了。所以在通常情況下ACK報文和FIN報文是分開發送的。

7.2 為什么TIME_WAIT 要等待2 * MSL秒后才釋放連接?

  1. 可靠的實現全雙工通信的終止

    TCP協議在關閉連接的4次握手中,最終ACK必須由發起終止的主機(A端)發送,如果這個ACK丟失,那么被終止端會重新發送FIN包。因此A端必須維護TIME_WAIT 允許他最終發送FIN包。如果A端不維護TIME_WAIT 而是直接處於Closed狀態,那么A端會給B相應一個RST,B端在收到會解析成一個錯誤(在Java中會拋出異常)

  2. 允許老的重復字節在網絡中消失

    TCP分節可能由於路由器異常而“迷途”,在迷途期間,TCP發送端可能因確認超時而重發這個分節,迷途的分節在路由器修復后也會被送到最終目的地,這個遲到的迷途分節到達時可能會引起問題。在關閉“前一個連接”之后,馬上又重新建立起一個相同的IP和端口之間的“新連接”,“前一個連接”的迷途重復分組在“前一個連接”終止后到達,而被“新連接”收到了。為了避免這個情況,TCP協議不允許處於TIME_WAIT狀態的連接啟動一個新的可用連接,因為TIME_WAIT狀態持續2MSL,就可以保證當成功建立一個新TCP連接的時候,來自舊連接重復分組已經在網絡中消逝。

</ssthresh時,擁塞窗口使用慢啟動算法,按指數級增長。>


免責聲明!

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



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