TCP定時器

1. TCP中7種定時器

 TCP中有7中定時器前端

(1)創建鏈接定時器(connection-establishment timer)服務器

(2)重傳定時器(retransmission timer)網絡

(3)延遲應答定時器(delayed ACK timer)tcp

(4)堅持定時器(persist timer)blog

(5)保活定時器(keepalive timers)隊列

(6)FIN_WAIT_2定時器(FIN_WAIT_2 timer)進程

(7)TIME_WAIT定時器(TIME_WAIT timer,也叫2MSL timer)ip

2. 創建鏈接定時器(connection-establishment timer)

這個定時器是在創建鏈接的時候使用的,TCP創建鏈接須要3次握手,如圖:資源

 

創建鏈接的過程當中,在發送SYN時,會啓動一個定時器(默認應該是3秒),若是SYN包丟失了,那麼3秒之後會從新發送SYN包(固然還會啓動一個新的定時器,設置成6秒超時),固然也不會一直沒完沒了的發SYN包,在/proc/sys/net/ipv4/tcp_syn_retries能夠設置到底要從新發送幾回SYN包。如圖:io

3. 重傳定時器(retransmission timer)

重傳定時器在TCP發送數據時設定,在計時器超時後沒有收到返回的確認ACK,發送端就會從新發送隊列中須要重傳的報文段。使用RTO重傳計時器通常有以下規則:
(1)當TCP發送了位於發送隊列最前端的報文段後就啓動這個RTO計時器
(2)若是隊列爲空則中止計時器,不然重啓定時器
(3)當計時器超時後,TCP會重傳發送隊列最前端的報文段
(4)當一個或多個報文段被累計確認後,這個貨這些報文段會被清除出隊列
重傳計時器保證了接收端可以接收到丟失的報文段,繼而保證了接收端交付給接收進程的數據始終是有序完整的。由於接收端永遠不會把一個失序不完整的報文段交付給接收進程。

4. 延遲應答定時器(delayed ACK timer)

延遲應答也被稱爲捎帶ACK,這個定時器是在延遲應答的時候使用的。爲何要延遲應答呢?延遲應答是爲了提供網絡傳輸的效率。
舉例說明,好比服務端收到客戶端的數據後,不是馬上回ACK給客戶端,而是等一段時間(通常最大200ms),這樣若是服務端要是有數據須要發給客戶端,那麼這個ACK就和服務端的數據一塊兒發給客戶端了,這樣比當即給客戶端一個ACK節省了一個數據包。

5. 堅持定時器(persist timer)

TCP經過讓接收方指明但願從發送方接收的數據字節數(即窗口大小)來進行流量控制。若是窗口大小爲0會發生什麼狀況呢?這將有效地阻止發送方傳送數據,直到窗口變爲非0爲止。接收端窗口變爲非0後,就會發送一個確認ACK指明須要的報文段序號以及窗口大小。
若是這個確認ACK丟失了,則雙方就有可能由於等待對方而使鏈接終止:接收方等待接收數據(由於它已經向發送方通告了一個非0的窗口),而發送方在等待容許它繼續發送數據的窗口更新。爲防止這種死鎖狀況的發生,發送方使用一個堅持定時器(persist timer)來週期性地向接收方查詢,以便發現窗口是否已增大。這些從發送方發出的報文段稱爲窗口探查(window probe)。

6. 保活定時器(keepalive timer)

許多TCP/IP的初學者會很驚奇地發現能夠沒有任何數據流經過一個空閒的TCP鏈接,也就是說,若是TCP鏈接的雙方都沒有向對方發送數據,則在兩個TCP模塊之間不交換任何信息。
兩個應用進程--客戶進程或服務器進程都沒有使用應用級的定時器來檢測非活動狀態,而這種非活動狀態能夠致使應用進程中的任何一個終止其活動。
許多時候服務器但願知道客戶主機是否崩潰並關機或崩潰又從新啓動,許多實現提供的保活定時器能夠提供這種能力。
保活功能主要是爲服務器應用程序提供的,服務器應用但願知道客戶主機是否崩潰。保活功能試圖在服務器端檢測到這種半開放的鏈接。

若是一個給定的鏈接在兩個小時以內沒有任何動做,則服務器就向客戶發送一個探查報文段,客戶主機必須處於一下4個狀態之一:
(1)客戶主機依然正常運行,並從服務器可達。客戶端TCP響應正常,而服務器也知道對方是正常工做的。服務器在兩個時之後將保活定時器復位。若是在兩個小時定時器到時間以前有應用程序的通訊量經過此連接,則定時器在交換數據後的將來2小時再復位
(2)客戶主機已經崩潰,而且關閉或正在從新啓動。在任何一種狀況下,客戶的TCP都沒有響應,服務器將不可以收到探查的響應。--會返回諸如「鏈接超時」之類的信息。
(3)客戶主機崩潰並已經從新啓動。這時服務器將收到一個對其保活探查的響應,可是這個響應是一個復位,使得服務器終止這個鏈接。 -- 會返回諸如「鏈接被對方復位」
(4)客戶主機正常運行,可是從服務器不可達。與(2)相同。

在TCP鏈接創建的時候指定了SO_KEEPALIVE,保活定時器纔會有效。若是客戶端和服務端長時間沒有數據交互,那麼須要保活定時器來判斷是否對端還活着,可是這個其實很不實用,由於默認是2小時沒有數據交互才探測,時間實在是太長了。若是你真的要確認對端是否活着,那麼應該本身實現心跳包,而不是依賴於這個保活定時器。

7. FIN_WAIT_2定時器(FIN_WAIT_2 timer)

主動關閉的一段調用完close以後(即發FIN給被動關閉的一段,而且收到其對FIN的確認ACK)則進入FIN_WAIT_2狀態。若是這個時候由於網絡忽然斷掉,被動關閉的一段宕機等緣由,致使主動關閉的一段不能收到被動關閉的一段發來的FIN,主動關閉的一端總不能一直等着,佔用資源不釋放吧。這個時候就須要FIN_WAIT_2定時器出馬了,若是在該定時器超時的時候,仍是沒收到被動關閉一端發來的FIN,那麼很差意思,不等了,直接釋放這個鏈接。FIN_WAIT_2定時器的時間能夠從/proc/sys/net/ipv4/tcp_fin_timeout中查看和設置。如圖:

8. TIME_WAIT定時器(TIME_WAIT timer,也叫2MSL timer)

TIME_WAIT是主動關閉鏈接的一端以後進入的狀態,而不是直接變成CLOSED的狀態,爲何呢?(1)萬一被動關閉的一端在超時時間內沒有收到最後一個ACK,則會重發最後的FIN,2MSL(報文段最大生存時間)等待時間保證了重發的FIN會被主動關閉的一端收到且從新發送最後一個ACK(2)另外一個緣由是在2MSL等待時間內,任何遲到的報文段會被接收並丟棄,防止老的TCP鏈接的包在新的TCP鏈接裏出現。不可避免,在這個2MSL等待時間呢,不會創建一樣(源IP、源端口、目的IP、目的端口)的鏈接。

相關文章
相關標籤/搜索