詳解四次斷開

興 走耳又發表於2020-09-28

簡述四次斷開(揮手)的過程

當客戶端與伺服器端進行資料傳輸完畢後,客戶端主動請求關閉,伺服器端被動關閉

第一次揮手:客戶端向伺服器端傳送FIN包(seq=1,FIN=1),並進入FIN-WAIT1狀態

第二次揮手:伺服器端收到客戶端傳送的的包,會回覆ACK確認包,表示收到,並進入CLOSE_WAIT 狀態,客戶端收到伺服器的ACK包會進入FIN_WAIT2狀態

第三次揮手: 伺服器端向客戶端傳送FIN+ACK包給客戶端,表示資料已經傳輸完畢,可以關閉了,並進入LAST_ACK,最後確認狀態。

第四次揮手:客戶端收到伺服器端傳送的包,回覆ACK確認包,表示收到,然後進入TIME_WAIT狀態,等待2MSL後進入CLOSE狀態,伺服器收到ACK確認包進入CLOSE狀態。

四次揮手完畢

為什麼是四次揮手?而不是三次?

三次握手是因為伺服器端在收到客戶端的syn請求包後,將ACK確認包和自己的SYN請求包合在一起傳送給客戶端了,而在結束時,客戶端向伺服器端傳送FIN包,僅僅表示自己沒有要傳輸的資料了,但這並不表示伺服器端沒有資料要傳輸給客戶端了,所以伺服器端在收到客戶端傳送的資料包後,會先傳送一個ACK確認包給客戶端,表示自己收到了,然後把自己的資料傳輸完畢,才會再次向伺服器端傳送FIN+ACK確認包,所以這就導致多出了一次。

為什麼要等待2MSL?

另一種問法:TIME_WAIT狀態是什麼意思?有什麼作用?

MSL(Maximum Segment Lifetime 最長的報文段壽命 或最長生命週期),TCP允許不同的實現可以設定不同的MSL值。

ACK 包到達伺服器需要 MSL 時間,伺服器重傳 FIN 包也需要 MSL 時間,2MSL 是資料包往返的最大時間,如果 2MSL 後還未收到伺服器重傳的 FIN 包,就說明伺服器已經收到了 ACK 包。

第一,保證客戶端傳送的最後一個ACK報文能夠到達伺服器,因為這個ACK報文可能丟失,站在伺服器的角度看來,
我已經傳送了FIN+ACK報文請求斷開了,客戶端還沒有給我回應,應該是我傳送的請求斷開報文它沒有收到,
於是伺服器又會重新傳送一次,而客戶端就能在這個2MSL時間段內收到這個重傳的報文,接著給出回應報文,並且會重啟2MSL計時器。

第二,防止類似與“三次握手”中提到了的“已經失效的連線請求報文段”出現在本連線中。客戶端傳送完最後一個確認報文後,
在這個2MSL時間中,就可以使本連線持續的時間內所產生的所有報文段都從網路中消失。這樣新的連線中不會出現舊連線的請求報文。

相關文章