TCP協議探究(二):超時與重試


1 概述

  • TCP提供可靠的運輸層。
  • 可靠性保證之一:確認從另一端收到的數據。
  • 但數據和確認都有可能會丟失。TCP通過在發送時設置一個定時器來解決這種問題。
  • 如果當定時器溢出時還沒有收到確認,它就重傳該數據。
  • TCP對於每個連接TCP管理4個不同的定時器:
    • 重傳定時器:使用於當希望收到另一端的確認。
    • 2MSL定時器:測量一個連接處於TIME_WAIT狀態的時間。
    • 堅持(persist)定時器:使窗口大小信息保持不斷流動,即使另一端關閉了其接收窗口
    • 保活(keepalive)定時器:用於檢測一個空閑連接的另一端何時崩潰或重啟。

2 TCP的狀態機

img

超時情況

  • 建立連接時SYN超時

    • client主動打開連接,發送SYN報文給server
    • server收到后被動打開,發送SYN+ACK報文給client,此時client直接下線
    • 導致server無法收到client的ACK報文,即該TCP連接既沒有建立也沒有斷開,所以server又會重傳SYN+ACK報文
    • 在Linux下,默認重試次數為5次,重試的間隔時間從1s開始每次都翻倍,5次的重試時間間隔為1s, 2s, 4s, 8s, 16s,總共31s,第5次發出后還要等32s都知道第5次也超時了,所以,總共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 2^6 -1 = 63s,TCP才會把斷開這個連接。
  • SYN Flood

    • 惡意偽造大量的TCP連接並斷開Client,導致Server維持了大量的TCP連接,且需要63秒后才會斷開,即63秒內的TCP連接數足夠多時,Server將承受不住,導致正常的連接不能處理。
    • 處理方案:
      • 減少Server的重試次數
      • 增大SYN的連接數
      • 處理不過來的連接直接丟棄
  • ISN的初始化

    • ISN不是每次建立建立連接時都從1開始
    • 問題:因為如果從1開始,client發送了30個segment給server,此時網絡斷開,過會client重連,又使用ISN=1來發送報文,但之前的報文已經送到了,即server認為client的ISN(初始化序列號)為30,但是實際上為1。
    • 解決方法:ISN會和一個假的時鍾綁在一起,這個時鍾會在每4微秒對ISN做加一操作,直到超過2^32,又從0開始。
    • MSL(Maximum Segment Lifetime):TCP段的最大存活時間,4ms*2^32=4.55小時,即TCP段存活時間不超過4.55小時就不會重用ISN。
  • MSL 和 TIME_WAIT:

    • 在TCP的狀態圖中,從TIME_WAIT狀態到CLOSED狀態,有一個超時設置,這個超時設置是 2 * MSL。
    • TIME_WAIT(2 * MSL):確保有足夠的時間讓對端收到了ACK,如果被動關閉的那方沒有收到Ack,就會觸發被動端重發FIN,一來一去正好不超過2 * MSL。
    • 有足夠的時間讓這個連接不會跟后面的連接混在一起(有些路由器會緩存IP數據包,導致連接被重用)。

3 TCP重試機制(發送方)

(1)概述

TCP要保證所有的數據包都到達,必需有重傳機制。

發送端發了1,2,3,4,5一共五份數據,接收端收到了1,2,於是回ack 3,然后收到了4(注意此時3沒收到),此時的TCP會怎么辦?

(2)超時重傳機制

  • 不回ACK,一直等待SN=3的到來,而發送方一直收不到3的ACK,就會超時重傳3.
  • 這種方式會有嚴重的問題,那就是死等3,所以導致4和5已經被收到了,而發送方也完全不知道(沒有收到ACK),所以發送方可能會悲觀地認為也丟了(即有可能導致4和5的重傳)。
  • 發送方的兩種選擇
    • 僅僅重傳timeout的包,節約寬帶,但是需要繼續等待后續報文ACK或者timeout重傳(效率低)。
    • 重傳timeout后的所有包,浪費寬帶,而且可能做了無用功。

(3)快速重傳機制

  • 如果發送方發出了1,2,3,4,5份數據,1先到了,於是就ack回2,結果2因為某些原因沒收到。3到達了,ack也回2,后面的4和5都到了,ack也回2(2沒有收到)。
  • 於是發送端收到了三個ack=2的確認,知道了2還沒有送達,於是重傳2(或者2之后的所有包)。然后接收端收到了2,此時3,4,5都收到了,於是ack回6。
  • 優點:不需要等待ACK超時,但是仍然沒有解決是重傳2還是重傳2與之后的所有包。

(4)SACK 方法

img

  • SACK回復可以告知發送端需要排除哪些報文進行發送
  • 該協議需要兩邊都支持。

強烈建議看看叔的文章

參考:https://coolshell.cn/articles/11564.html


免責聲明!

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



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