TCP協議的TIME_WAIT狀態詳解

TCP協議的TIME_WAIT狀態詳解

我發現有個公司面試的時候問了對TCP協議比較細節的地方,那就寫一下幫助本身加深理解和記憶。在開始說TIME_WAIT狀態以前,要知道TCP協議是如何關閉鏈接的。
不少人對TCP協議的三次握手都很熟悉(不知道的能夠參考我之前的帖子),由於學校的垃圾考試都愛考三次握手,可是不少知道三次握手的人都對TCP協議是如何關閉鏈接不瞭解。不說廢話了,TCP關閉鏈接過程以下圖,寡人用photoshop畫的,湊合看一下:
tcpclose
爲了方便描述,我給這個TCP鏈接的一端起名爲Client,給另一端起名爲Server。上圖描述的是Client主動關閉的過程,FTP協議中就這樣的。若是要描述Server主動關閉的過程,只要交換描述過程當中的Server和Client就能夠了,HTTP協議就是這樣的。 面試

描述過程:
Client調用close()函數,給Server發送FIN,請求關閉鏈接;Server收到FIN以後給Client返回確認ACK,同時關閉讀通道(不清楚就去看一下shutdown和close的差異),也就是說如今不能再從這個鏈接上讀取東西,如今read返回0。此時Server的TCP狀態轉化爲CLOSE_WAIT狀態。
Client收到對本身的FIN確認後,關閉 寫通道,再也不向鏈接中寫入任何數據。
接下來Server調用close()來關閉鏈接,給Client發送FIN,Client收到後給Server回覆ACK確認,同時Client關閉讀通道,進入TIME_WAIT狀態。
Server接收到Client對本身的FIN的確認ACK,關閉寫通道,TCP鏈接轉化爲CLOSED,也就是關閉鏈接。
Client在TIME_WAIT狀態下要等待最大數據段生存期的兩倍,而後才進入CLOSED狀態,TCP協議關閉鏈接過程完全結束。 網絡

以上就是TCP協議關閉鏈接的過程,如今說一下TIME_WAIT狀態。
從上面能夠看到,主動發起關閉鏈接的操做的一方將達到TIME_WAIT狀態,並且這個狀態要保持Maximum Segment Lifetime的兩倍時間。爲何要這樣作而不是直接進入CLOSED狀態? socket

緣由有二:
1、保證TCP協議的全雙工鏈接可以可靠關閉
2、保證此次鏈接的重複數據段從網絡中消失
tcp

先說第一點,若是Client直接CLOSED了,那麼因爲IP協議的不可靠性或者是其它網絡緣由,致使Server沒有收到Client最後回覆的ACK。那麼Server就會在超時以後繼續發送FIN,此時因爲Client已經CLOSED了,就找不到與重發的FIN對應的鏈接,最後Server就會收到RST而不是ACK,Server就會覺得是鏈接錯誤把問題報告給高層。這樣的狀況雖然不會形成數據丟失,可是卻致使TCP協議不符合可靠鏈接的要求。因此,Client不是直接進入CLOSED,而是要保持TIME_WAIT,當再次收到FIN的時候,可以保證對方收到ACK,最後正確的關閉鏈接。 函數

再說第二點,若是Client直接CLOSED,而後又再向Server發起一個新鏈接,咱們不能保證這個新鏈接與剛關閉的鏈接的端口號是不一樣的。也就是說有可能新鏈接和老鏈接的端口號是相同的。通常來講不會發生什麼問題,可是仍是有特殊狀況出現:假設新鏈接和已經關閉的老鏈接端口號是同樣的,若是前一次鏈接的某些數據仍然滯留在網絡中,這些延遲數據在創建新鏈接以後纔到達Server,因爲新鏈接和老鏈接的端口號是同樣的,又由於TCP協議判斷不一樣鏈接的依據是socket pair,因而,TCP協議就認爲那個延遲的數據是屬於新鏈接的,這樣就和真正的新鏈接的數據包發生混淆了。因此TCP鏈接還要在TIME_WAIT狀態等待2倍MSL,這樣能夠保證本次鏈接的全部數據都從網絡中消失。 大數據

各類協議都是前人千錘百煉後獲得的標準,規範。從細節中都能感覺到精巧和嚴謹。每次深刻都有同一個感受,精妙。 spa

相關文章
相關標籤/搜索