TCP的堅持定時器


引言

TCP通過讓接收方指明希望從發送方接收的數據字節數(即窗口大小)來進行流量控制。如果窗口大小為 0會發生什么情況呢?這將有效地阻止發送方傳送數據,直到窗口變為非0為止。
TCP不對ACK報文段進行確認, TCP只確認那些包含有數據的ACK報文段。
如果一個確認丟失了,則雙方就有可能因為等待對方而使連接終止:接收方等待接收數據(因為它已經向發送方通告了一個非 0的窗口),而發送方在等待允許它繼續發送數據的窗口更新。為防止這種死鎖情況的發生,發送方使用一個堅持定時器 (persist timer)來周期性地向接收方查詢,以便發現窗口是否已增大。這些從發送方發出的報文段稱為窗口探查 (window  probe)。

一個例子

為了觀察到實際中的堅持定時器,我們啟動一個接收進程。它監聽來自客戶的連接請求,接受該連接請求,然后在從網上讀取數據前休眠很長一段時間。
sock程序可以通過指定一個暫停選項 - P使服務器在接受連接和進行第一次讀動作之間進入休眠。我們以這種方式調用服務器:

svr4 % sock -i -s -P100000 5555

該命令在從網絡上讀數據之前休眠 100 000秒(27.8小時)。客戶運行在主機bsdi上,並向服務器的5555端口執行1024字節的寫操作。下圖給出了tcpdump的輸出結果(我們已經在結果中去掉了連接的建立過程)。
報文段1 ~ 1 3顯示的是從客戶到服務器的正常的數據傳輸過程,有9216個字節的數據填充了窗口。服務器通告窗口大小為4096字節,且默認的插口緩存大小為4096字節。但實際上它一共接收了9216字節的數據,這是在S V R 4中TCP代碼和流子系統(stream subsystem)之間某種形式交互的結果。
在報文段1 3中,服務器確認了前面 4個數據報文段,然后通告窗口為 0,從而使客戶停止發送任何其他的數據。這就引起客戶設置其堅持定時器。如果在該定時器時間到時客戶還沒有接收到一個窗口更新,它就探查這個空的窗口以決定窗口更新是否丟失。由於服務器進程處於休眠狀態,所以TCP緩存9216字節的數據並等待應用進程讀取。
請注意客戶發出的窗口探查之間的時間間隔。在收到一個大小為 0的窗口通告后的第1個(報文段1 4)間隔為4.949秒,下一個(報文段16)間隔是4.996秒,隨后的間隔分別約為6,12,24,48和60秒。

為什么這些間隔總是比5、6、12、24、48和60小一個零點幾秒呢?因為這些探查被TCP的500 ms定時器超時例程所觸發。當定時器時間到時,就發送窗口探查,並大約在4 ms之后收到一個應答。
接收到應答使得定時器被重新啟動,但到下一個時鍾滴答之間的時間則約為500減4ms。計算堅持定時器時使用了普通的 TCP指數退避。對一個典型的局域網連接,首次超時時間算出來是1 . 5秒,第2次的超時值增加一倍,為 3秒,再下次乘以4為6秒,之后再乘以8為1 2秒等。但是堅持定時器總是在5 ~ 6 0秒之間,這與我們在上圖中觀察到的現象一致。
窗口探查包含一個字節的數據(序號為 9 2 1 7)。TCP總是允許在關閉連接前發送一個字節的數據。請注意,盡管如此,所返回的窗口為0的ACK並不是確認該字節(它們確認了包括9216在內的所有數據),因此這個字節被持續重傳。
堅持狀態與重傳超時之間一個不同的特點就是 TCP從不放棄發送窗口探查。這些探查每隔60秒發送一次,這個過程將持續到或者窗口被打開,或者應用進程使用的連接被終止。

 

本文轉自 《TCP/IP詳解》卷1


免責聲明!

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



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