1. 程式人生 > >解讀TCP 四種定時器

解讀TCP 四種定時器

行記錄 現在 接收數據 打開 的確 strong 滑動 sed 窗口大小

對於每個連接,TCP 管理著四個不同的定時器:重傳定時器、堅持定時器、保活定時器 以及 2MSL 定時器。

重傳定時器

為了防止丟失數據報文段或確認報文段,當 TCP 發送報文段時,啟動了特定報文段的重傳計時器,若在計時器超時之前收到對報文段的確認,則撤銷計時器。若收到特定報文段的確認之前計時器已經超時,則重傳該報文,並把計時器復位。這裏最重要的是超時的時間計算,有關該時間的請查閱具體的算法,這裏不再進行記錄。

堅持定時器

堅持定時器主要是解決零窗口大小通知可能導致的死鎖問題。剛開始接收端向發送端發送了一個零窗口報文段。在不久之後,如果接收端的緩存區有一定的空間可以接收數據,此時接收端就會向發送端發送了一個非零窗口大小的報文段(即窗口更新),但是這個非零窗口大小的報文段在傳輸過程中丟失,導致發送端無法接收到該非零窗口大小的報文段。因此,發送端就會一直處於等待非零窗口大小的報文端通知,由於接收端已經發送了非零窗口大小的報文段,而且並不知道該報文段在傳輸過程中丟失,則接收端會一直處於等待接收數據狀態,如果沒有任何措施的話,這個死鎖的局面會一直延續下去。

為了解決上面這個問題,TCP 為每一個連接設有一個堅持定時器(也叫持續計數器)。當發送端收到零窗口的確認時,就啟動堅持計時器,當堅持計時器截止期到時,發送端就發送一個特殊的報文段,叫探測報文段,這個報文段只有一個字節的數據。探測報文段有序號,但序號永遠不需要確認,甚至在計算對其他部分數據的確認時這個序號也被忽略。探測報文段提醒接收端,確認已丟失,必須重傳。

堅持計時器的截止期設置為重傳時間的值,但若沒有收到來自接收端的響應,則發送另一個探測報文段,並將堅持計時器的值加倍和並復位,發送端繼續發送探測報文段,將堅持計時器的值加倍和復位,直到這個值增大到閾值為止(通常為 60 秒)。在此之後,發送端每隔 60s 就發送一個報文段,直到窗口重新打開為止。

堅持定時器的原理:當 TCP 服務器收到了客戶端的 0 滑動窗口報文時,啟動一個定時器來計時,並在定時器溢出的時向客戶端查詢窗口是否已經增大,如果得到非零的窗口就重新開始發送數據,如果得到零窗口就再開一個新的定時器準備下一次查詢。

保活定時器

保活定時器是為了應對 TCP 連接雙方出現長時間的沒有數據傳輸的情況。如果客戶端與服務器建立了 TCP 連接之後,客戶端由於某種原因導致主機故障,則服務器就不能收到來自客戶端的數據,而服務器不可能一直處於等待狀態,保活定時器就是用來解決這個問題的。服務器每收到一次客戶端的數據,就重新設置保活定時器,通常為 2 小時,如果 2 小時沒有收到客戶端的數據,服務端就發送一個探測報文,以後每隔75秒發送一次,如果連續發送10次探測報文段後仍沒有收到客戶端的響應,服務器就認為客戶端出現了故障,就可以終止這個連接。

2MSL 定時器

2MSL 定時器主要是解決以下兩種情況:

TIME_WAIT 確保有足夠的時間讓對端收到了ACK,如果被動關閉的那方沒有收到 ACK,就會觸發被動端重發 FIN。因為最後一次確認應答 ACK 報文段很有可能丟失,因而使被動關閉方處於在LIST_ACK 狀態的,此時被動關閉方會重發這個 FIN+ACK 報文段,在這等待的 2MSL 時間內主動關閉方重新收到這個被動關閉方重發的 FIN+ACK 報文段,因此,主動關閉方會重新發送確認應答信息,從而重新啟動 2MSL 計時器,直到通信雙方都進入 CLOSED 狀態。如果主動關閉方在 TIME_WAIT 狀態不等待一段時間就直接釋放連接並進入 CLOSED 狀態,那麽主動關閉方無法收到來自被動關閉方重發的 FIN+ACK 報文段,也就不會再發送一次確認 ACK 報文段,因此被動關閉方就無法正常進入CLOSED 狀態。

有足夠的時間讓這個連接不會跟後面的連接混在一起。防止已失效的請求連接出現在本連接中。在連接處於 2MSL 等待時,任何遲到的報文段將被丟棄,因為處於 2MSL等待的、由該插口(插口是IP和端口對的意思,socket)定義的連接在這段時間內將不能被再用,這樣就可以使下一個新的連接中不會出現這種舊的連接之前延遲的報文段

轉自:http://network.51cto.com/art/201412/459352.htm

解讀TCP 四種定時器