TCP斷開連接的相關問題


1.TCP四次揮手過程和狀態變遷

  TCP斷開連接時通過四次揮手方式,雙方都可以主動斷開連接,斷開連接后主機中的資源將被釋放。

  

   (1)客戶端打算關閉連接,此時會發送一個TCP首部FIN標志位被置為1的報文,即FIN報文,之后客戶端進入FIN_WAIT_1狀態。

  (2)服務端收到該報文后,就向客戶端發送ACK應答報文,接着服務端進入CLOSED_WAIT狀態。

  (3)客戶端收到服務端的ACK應答報文后,之后進入FIN_WAIT_2狀態。

  (4)等待服務端處理完數據后,也向客戶端發送FIN報文,之后服務端進入LAST_ACK狀態。

  (5)客戶端收到服務端的FIN報文后,回一個ACK應答報文,之后進入TIME_WAIT狀態。

  (6)服務端收到了ACK應答報文后,就進入CLOSE狀態,至此服務端已經完成連接的關閉。

  (7)客戶端在經過2MSL時間后,自動進入CLOSE狀態,至此客戶端也完成連接的關閉。

  每個方向都需要一個FIN和一個ACK,因此通常被稱為四次揮手。

  這里值得注意的是:主動關閉連接的,才有TIME_WAIT狀態。

2.為什么揮手需要四次?

  關閉連接時,客戶端向服務端發送FIN報文時,僅僅表示客戶端不再發送數據了但是還能夠接收數據;

  服務器收到客戶端的FIN報文時,先回一個ACK應答報文,而服務端可能還有數據需要處理和發送,等服務端不再發送數據時,才發送FIN報文給客戶端表示同意現在關閉連接。

  所以說,服務端通常需要等待完成數據的發送和處理,所以服務端的ACK和FIN一般都會分開發送,從而比三次握手多了一次。

3.為什么TIME_WAIT等待的時間是2MSL?

  MSL是報文的最大生存時間(Maximum Segment Lifetime),它是任何報文在網絡上存在的最長時間,超過這個時間報文就會被丟棄。因為TCP報文基於IP協議的,而IP頭中有一個TTL字段,是IP數據報可以經過的最大路由數,每經過一個處理它的路由器,此值就減1,當這個值為0時,就表示數據報將被丟棄,同時發送ICMP報文通知源主機。MSL和TTL的區別是:MSL的單位是時間,而TTL是經過路由跳數,所以MSL應該要大於等於TTL消耗為0的時間,以確保報文已被自然消亡。

  TIME_WAIT等待2倍的MSL:網絡中可能存在來自發送方的數據包,當這些數據包被接收方處理后又會向對方發送響應,所以一來一回需要等待2倍的時間。

  比如,如果被動關閉方沒有收到斷開連接的最后的ACK報文,就會觸發超時重發FIN報文,另一方接收到FIN后,會重發ACK給被動關閉方,一來一去正好是2個MSL。這個時間是從客戶端收到FIN后發送ACK開始計時的,如果在TIME_WAIT時間內,應為客戶端的ACK沒有傳輸到服務端,客戶端又收到了服務端重發的FIN報文,那么2MSL時間將重新計時。

4.為什么需要TIME_WAIT狀態?

  主動關閉連接的一方才會有TIME_WAIT狀態。

  (1)原因一:防止舊連接的數據包

  如果TIME_WAIT沒有等待時間或者時間過短,被延遲的數據包抵達會發生什么?

 

   服務端在關閉連接之前發送SEQ=301報文,被網絡延遲,這時有相同端口的TCP連接被復用后,被延遲的SEQ=301抵達了客戶端,那么客戶端有可能正常接收這個過期的報文,這就會產生數據錯亂等嚴重的問題。所以,TCP中有2MSL這個時間,足以讓兩個方向上的數據包都被丟棄,使得原來連接的數據包在網絡中都自然消失,再出現的數據包一定都是在新建立連接所產生的。

 (2)保證連接正確關閉

  等待足夠的時間以確保最后的ACK能讓被動關閉方接收,從而幫助其正常關閉。

  

   如果客戶端四次揮手的最后一個ACK報文在網絡中被丟失,此時如果客戶端TIME_WAIT過短或沒有,就直接進入了CLOSE狀態,那么服務端就會一直處於LAST_ACK狀態。當客戶端發起建立連接的SYN請求報文后,服務端會發送RST報文給客戶端,連接建立的過程就會被中止。

  而如果TIME_WAIT等待時間足夠長的話:(1)服務端正常接收到四次揮手的最后一個ACK報文,則服務端正常關閉連接。(2)服務端沒有收到四次揮手的最后一個ACK報文,重發FIN關閉連接報文等待新的ACK報文。

  所以,客戶端在TIME_WAIT狀態等待2MSL時間后,就可以保證雙方的連接都可以正常關閉。

5.TIME_WAIT過多有什么危害?

  如果服務器有處於TIME_WAIT狀態的TCP,則說明是由服務器方主動發起的斷開請求。過多的TIME_WAIT狀態的危害有:

  • 對內存資源的占用;
  • 對端口資源的占用,一個TCP連接至少消耗一個本地端口,如果TIME_WAIT狀態過多,占滿了所有的端口資源,則會導致無法建立新的連接。  

6.如果已經建立了連接,但是客戶端突然出現了故障了怎么辦?

  TCP中有一個保活機制,這個機制的原理是:

  定義一個時間段,在這個時間段,如果沒有任何連接相關的活動,TCP保活機制會開始作用,每隔一個時間間隔,發送一個探測報文,該探測報文包含的數據非常少,如果連續幾個探測報文都沒有得到響應,則認為當前的TCP連接已經死亡,系統內核將錯誤信息通知給上層應用程序。

  如果開啟了TCP保活,需要考慮這三種情況:

  • 對端程序是正常工作的,當TCP保活的探測報文發送給對端,對端會正常響應,這樣TCP保活時間會被重置,等待下一個TCP保活時間的到來;
  • 對端程序崩潰並重啟,當TCP保活的探測報文發送給對端后,對端是可以響應的,但由於沒有該連接的有效信息,會產生一個RST報文,這樣很快就會發現TCP連接已經被重置;
  • 對端程序崩潰或對端由於其他原因導致報文不可達,當TCP保活的探測報文發送給對端后,石沉大海,沒有響應,連續幾次,達到保活探測次數后,TCP匯報該TCP連接已經死亡。

參考文獻:https://mp.weixin.qq.com/s/ihDCVCI4jm24XDZ9bCTfqQ


免責聲明!

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



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