TCP斷開連接爲什麽需要4次揮手?

程序員小迷 2024-04-19 17:17:02

一、斷開連接過程

由于TCP連接是全雙工的,因此每個方向都必須單獨關閉。客戶端在數據發送完畢後發送一個結束數據段FIN,且服務端也返回確認數據段ACK,此時結束了客戶端到服務端的連接;然後客戶端接收到服務端發送的FIN,且服務端也收到了客戶端發送的ACK之後,自此雙方的數據通信完全結束。簡單說來是 "先關讀,後關寫",一共需要四個階段:服務器讀通道關閉->客戶機寫通道關閉->客戶機讀通道關閉->服務器寫通道關閉。

4次揮手中的每次"揮手"(即報文交換)都是對之前動作的確認,確保了數據的可靠傳輸直到連接完全關閉。例如,客戶端發送FIN後進入FIN-WAIT-1狀態,等待服務端的ACK;服務端收到FIN後發送ACK,並進入CLOSE-WAIT狀態繼續發送剩余數據,之後再發送FIN;客戶端收到ACK後進入FIN-WAIT-2狀態,收到服務端的FIN後發送最後一個ACK,並進入TIME-WAIT狀態等待可能滯後的服務端數據報文,確認沒有未送達的數據後,連接最終關閉。

二、需要4次揮手的原因

1.雙方均可主動關閉:

與三次握手類似,4次揮手確保了雙方都能夠有序地關閉連接。雙方都可以主動發起關閉連接的過程。

2.確認數據接收:

通過4次揮手過程中的ACK報文,每一方都確認收到了對方的FIN報文,確保了數據被可靠傳輸。

3.避免數據丟失:

在關閉連接之前,必須保證已經發送的數據被對方接收,同時也要允許對方發送的數據被本端接收。4次揮手過程提供了這樣的機制,確保數據不會因爲連接的關閉而丟失。

4.全雙工通信:

TCP是全雙工協議,意味著數據可以在兩個方向上同時傳輸。因此,每個方向上的連接都需要獨立關閉。每個方向上都要經曆一次"我已完成發送"(FIN,Finish)的信號交換和對方對此的確認(ACK,Acknowledgment)。由于關閉連接涉及兩個方向,所以至少需要兩次這樣的信號交換,總共4次揮手。這就是爲什麽需要兩次FIN和兩次ACK的原因。

5.關閉順序的靈活性: 任一端(客戶端或服務端)都可以主動發起關閉連接的請求。當一方(例如客戶端)完成數據發送並准備關閉連接時,它會發送一個FIN報文給另一方(服務端)。服務端收到FIN後,確認已收到(發送ACK),但此時服務端可能還在發送數據或需要一些時間來清理資源。服務端完成數據發送後,也會發送自己的FIN報文給客戶端,客戶端再回複ACK確認。這種雙向的關閉過程確保雙方都同意關閉,並且各自的數據傳輸都已經結束。

6.等待足夠時間:

在第4次揮手中,最初發送FIN報文的一方在發送ACK報文後,需要等待一段時間2*MSL(MSL:Maximum Segment  Lifetime報文段最大生存時間,它是任何報文段被丟棄前在網絡內的最長時間),以確保對方收到了這個ACK報文。這個過程稱爲TIME_WAIT狀態,它有助于確保遠程端正確關閉連接,並允許遲到的數據包到達。

7.資源釋放:

4次揮手過程還負責適當地釋放在建立連接時分配的資源,如端口號、內存緩沖區等。

8.保持一致性:

4次揮手保持了與三次握手過程的一致性。雖然它們的目的不同(三次握手用于建立連接,4次揮手用于斷開連接),但都是爲了保證TCP連接的可靠性和穩定性。

三、總結

總的來說,4次揮手是TCP協議爲了確保連接可靠、有序地關閉而設計的,它允許雙方都能完成數據的發送和確認,避免了數據丟失,並且確保了資源的合理釋放。

致力于C、C++、Java、Kotlin、Android、Shell、JavaScript、TypeScript、Python等編程技術的技巧經驗分享。

若作品對您有幫助,請關注、分享、點贊、收藏、在看、喜歡。您的支持是我們爲您提供幫助的最大動力。

0 阅读:0

程序員小迷

簡介:致力于Android、C等編程技術的技巧經驗分享