1. 程式人生 > >面試總結之time_wait狀態產生的原因,危害,如何避免

面試總結之time_wait狀態產生的原因,危害,如何避免

前言

請說說你對TCP連線中time_wait狀態的理解

解答:

先上TCP的狀態變遷圖

1. time_wait狀態如何產生?  由上面的變遷圖,首先呼叫close()發起主動關閉的一方,在傳送最後一個ACK之後會進入time_wait的狀態,也就說該傳送方會保持2MSL時間之後才會回到初始狀態。MSL值得是資料包在網路中的最大生存時間。產生這種結果使得這個TCP連線在2MSL連線等待期間,定義這個連線的四元組(客戶端IP地址和埠,服務端IP地址和埠號)不能被使用。

2.time_wait狀態產生的原因

1)為實現TCP全雙工連線的可靠釋放

由TCP狀態變遷圖可知,假設發起主動關閉的一方(client)最後傳送的ACK在網路中丟失,由於TCP協議的重傳機制,執行被動關閉的一方(server)將會重發其FIN,在該FIN到達client之前,client必須維護這條連線狀態,也就說這條TCP連線所對應的資源(client方的local_ip,local_port)不能被立即釋放或重新分配,直到另一方重發的FIN達到之後,client重發ACK後,經過2MSL時間週期沒有再收到另一方的FIN之後,該TCP連線才能恢復初始的CLOSED狀態。如果主動關閉一方不維護這樣一個TIME_WAIT狀態,那麼當被動關閉一方重發的FIN到達時,主動關閉一方的TCP傳輸層會用RST包響應對方,這會被對方認為是有錯誤發生,然而這事實上只是正常的關閉連線過程,並非異常。

2)為使舊的資料包在網路因過期而消失

為說明這個問題,我們先假設TCP協議中不存在TIME_WAIT狀態的限制,再假設當前有一條TCP連線:(local_ip, local_port, remote_ip,remote_port),因某些原因,我們先關閉,接著很快以相同的四元組建立一條新連線。本文前面介紹過,TCP連線由四元組唯一標識,因此,在我們假設的情況中,TCP協議棧是無法區分前後兩條TCP連線的不同的,在它看來,這根本就是同一條連線,中間先釋放再建立的過程對其來說是“感知”不到的。這樣就可能發生這樣的情況:前一條TCP連線由local peer傳送的資料到達remote peer後,會被該remot peer的TCP傳輸層當做當前TCP連線的正常資料接收並向上傳遞至應用層(而事實上,在我們假設的場景下,這些舊資料到達remote peer前,舊連線已斷開且一條由相同四元組構成的新TCP連線已建立,因此,這些舊資料是不應該被向上傳遞至應用層的),從而引起資料錯亂進而導致各種無法預知的詭異現象。作為一種可靠的傳輸協議,TCP必須在協議層面考慮並避免這種情況的發生,這正是TIME_WAIT狀態存在的第2個原因。

3)總結  具體而言,local peer主動呼叫close後,此時的TCP連線進入TIME_WAIT狀態,處於該狀態下的TCP連線不能立即以同樣的四元組建立新連線,即發起active close的那方佔用的local port在TIME_WAIT期間不能再被重新分配。由於TIME_WAIT狀態持續時間為2MSL,這樣保證了舊TCP連線雙工鏈路中的舊資料包均因過期(超過MSL)而消失,此後,就可以用相同的四元組建立一條新連線而不會發生前後兩次連線資料錯亂的情況。

3.time_wait狀態如何避免

首先伺服器可以設定SO_REUSEADDR套接字選項來通知核心,如果埠忙,但TCP連線位於TIME_WAIT狀態時可以重用埠。在一個非常有用的場景就是,如果你的伺服器程式停止後想立即重啟,而新的套接字依舊希望使用同一埠,此時SO_REUSEADDR選項就可以避免TIME_WAIT狀態。 ---------------------  作者:Rock_N_Roll_  來源:CSDN  原文:https://blog.csdn.net/u013616945/article/details/77510925  版權宣告:本文為博主原創文章,轉載請附上博文連結!