socket程式設計二十 TCP四次握手斷開連線

2021-09-22 14:14:42 字數 1480 閱讀 7340

建立連線非常重要,它是資料正確傳輸的前提;斷開連線同樣重要,它讓計算機釋放不再使用的資源。如果連線不能正常斷開,不僅會造成資料傳輸錯誤,還會導致套接字不能關閉,持續占用資源,如果併發量高,伺服器壓力堪憂。

建立連線需要三次握手,斷開連線需要四次握手,可以形象的比喻為下面的對話:

下圖演示了客戶端主動斷開連線的場景:

建立連線後,客戶端和伺服器都處於establised狀態。這時,客戶端發起斷開連線的請求:

1) 客戶端呼叫 close() 函式後,向伺服器傳送 fin 資料報,進入fin_wait_1狀態。fin 是 finish 的縮寫,表示完成任務需要斷開連線。

2) 伺服器收到資料報後,檢測到設定了 fin 標誌位,知道要斷開連線,於是向客戶端傳送「確認包」,進入close_wait狀態。

注意:伺服器收到請求後並不是立即斷開連線,而是先向客戶端傳送「確認包」,告訴它我知道了,我需要準備一下才能斷開連線。

3) 客戶端收到「確認包」後進入fin_wait_2狀態,等待伺服器準備完畢後再次傳送資料報。

4) 等待片刻後,伺服器準備完畢,可以斷開連線,於是再主動向客戶端傳送 fin 包,告訴它我準備好了,斷開連線吧。然後進入last_ack狀態。

5) 客戶端收到伺服器的 fin 包後,再向伺服器傳送 ack 包,告訴它你斷開連線吧。然後進入time_wait狀態。

6) 伺服器收到客戶端的 ack 包後,就斷開連線,關閉套接字,進入closed狀態。

客戶端最後一次傳送 ack包後進入 time_wait 狀態,而不是直接進入 closed 狀態關閉連線,這是為什麼呢?

tcp 是面向連線的傳輸方式,必須保證資料能夠正確到達目標機器,不能丟失或出錯,而網路是不穩定的,隨時可能會毀壞資料,所以機器a每次向機器b傳送資料報後,都要求機器b」確認「,回傳ack包,告訴機器a我收到了,這樣機器a才能知道資料傳送成功了。如果機器b沒有回傳ack包,機器a會重新傳送,直到機器b回傳ack包。

客戶端最後一次向伺服器回傳ack包時,有可能會因為網路問題導致伺服器收不到,伺服器會再次傳送 fin 包,如果這時客戶端完全關閉了連線,那麼伺服器無論如何也收不到ack包了,所以客戶端需要等待片刻、確認對方收到ack包後才能進入closed狀態。那麼,要等待多久呢?

資料報在網路中是有生存時間的,超過這個時間還未到達目標主機就會被丟棄,並通知源主機。這稱為報文最大生存時間(msl,maximum segment lifetime)。time_wait 要等待 2msl 才會進入 closed 狀態。ack 包到達伺服器需要 msl 時間,伺服器重傳 fin 包也需要 msl 時間,2msl 是資料報往返的最大時間,如果 2msl 後還未收到伺服器重傳的 fin 包,就說明伺服器已經收到了 ack 包。

tcp 四次揮手 TCP四次揮手

tcp斷開連線的過程 客戶端傳送fin報文,表明客戶端將不在傳送資料。具體過程 把fin標誌位改為1,序號seq u,之前傳送的資料加1,這裡規定即使不攜帶資料序號也要 1。該過程中客戶端通過close系統呼叫從established狀態進入fin wait 1狀態。第二次揮手 服務端收到客戶端發來...

TCP四次揮手

純給自己看的 發起關閉的一方是客戶端,被動關閉的一方是伺服器。1 客戶端a傳送乙個fin 1,用來關閉客戶a到伺服器b的資料傳送。圖上畫的對,還有乙個seq n 2 伺服器b收到這個fin,它發回乙個ack 1,確認序號ack為收到的序號加1。3 伺服器b關閉與客戶端a的連線,傳送乙個fin 1給客...

TCP四次揮手

四次揮手 1.客戶端程序發出連線釋放報文,並且停止傳送資料。釋放資料報文首部,fin 1,其序列號為seq u 等於前面已經傳送過來的資料的最後乙個位元組的序號加1 此時,客戶端進入fin wait 1 終止等待1 狀態。tcp規定,fin報文段即使不攜帶資料,也要消耗乙個序號。2.伺服器收到連線釋...