三次握手和四次揮手的實現原理,以及為什么要這樣設計?
- 三次握手的實現
- 三次握手的核心角色與參數
- 三次握手的具體步驟
- 第一步:客戶端 → 服務器(發送 `SYN` 報文)
- 第二步:服務器 → 客戶端(發送 `SYN+ACK` 報文)
- 第三步:客戶端 → 服務器(發送 `ACK` 報文)
- 三次握手的核心目的
- 為什么需要三次握手,而不是兩次?
- 總結
- 四次揮手的實現
- 四次揮手的核心背景
- 四次揮手的具體步驟
- 第一步:客戶端 → 服務器(發送 `FIN` 報文)
- 第二步:服務器 → 客戶端(發送 `ACK` 報文)
- 第三步:服務器 → 客戶端(發送 `FIN` 報文)
- 第四步:客戶端 → 服務器(發送 `ACK` 報文)
- 四次揮手的核心目的
- 為什么需要四次揮手,而不是三次?
- 總結
三次握手的實現
TCP 三次握手(Three-Way Handshake)是建立 TCP 連接的核心過程,其目的是確保客戶端和服務器雙方的發送能力與接收能力均正常,并協商初始序列號(用于后續數據傳輸的有序性和完整性校驗)。以下是詳細過程:
三次握手的核心角色與參數
- 客戶端:主動發起連接的一方(如瀏覽器)。
- 服務器:被動接受連接的一方(如 Web 服務器)。
- 序列號(Sequence Number,
seq
):發送方為每個數據包分配的唯一編號,用于接收方確認數據順序和完整性(避免重復或丟失)。 - 確認號(Acknowledgment Number,
ack
):接收方告知發送方“已收到的最大序列號 + 1”,表示期望接收的下一個數據編號。 - 標志位:
SYN
(Synchronize):用于發起連接,請求同步序列號。ACK
(Acknowledgment):用于確認已收到數據。
三次握手的具體步驟
第一步:客戶端 → 服務器(發送 SYN
報文)
-
客戶端行為:
客戶端向服務器發送一個SYN
報文(同步請求),表示“我想和你建立連接”。
報文中包含:- 標志位:
SYN = 1
(表示這是一個連接請求)。 - 初始序列號:
seq = x
(x
是客戶端隨機生成的 32 位整數,如1000
)。
- 標志位:
-
服務器狀態變化:
服務器收到SYN
報文后,從“關閉狀態”進入“同步收到狀態(SYN-RCVD)”,表示“已收到連接請求,準備回應”。
第二步:服務器 → 客戶端(發送 SYN+ACK
報文)
-
服務器行為:
服務器向客戶端回復一個SYN+ACK
報文(同步 + 確認),表示“我收到了你的請求,也想和你建立連接”。
報文中包含:- 標志位:
SYN = 1
(服務器發起自己的同步請求)、ACK = 1
(確認收到客戶端的請求)。 - 服務器的初始序列號:
seq = y
(y
是服務器隨機生成的整數,如2000
)。 - 確認號:
ack = x + 1
(表示“已收到客戶端序列號為x
的報文,下一次期望接收x+1
及以后的數據”)。
- 標志位:
-
客戶端狀態變化:
客戶端收到SYN+ACK
報文后,從“同步發送狀態(SYN-SENT)”進入“建立連接狀態(ESTABLISHED)”,表示“確認服務器已準備好,連接即將建立”。
第三步:客戶端 → 服務器(發送 ACK
報文)
-
客戶端行為:
客戶端向服務器發送一個ACK
報文(確認),表示“我收到了你的回應,連接可以正式建立了”。
報文中包含:- 標志位:
ACK = 1
(僅確認,無新的同步請求)。 - 客戶端的序列號:
seq = x + 1
(基于第一步的x
遞增,符合 TCP 序列號連續的規則)。 - 確認號:
ack = y + 1
(表示“已收到服務器序列號為y
的報文,下一次期望接收y+1
及以后的數據”)。
- 標志位:
-
服務器狀態變化:
服務器收到ACK
報文后,從“同步收到狀態(SYN-RCVD)”進入“建立連接狀態(ESTABLISHED)”,表示“雙方確認完畢,TCP 連接正式建立”。
三次握手的核心目的
-
驗證雙向通信能力:
- 第一步:客戶端確認服務器“能接收”(服務器收到
SYN
)。 - 第二步:服務器確認客戶端“能發送也能接收”(客戶端收到
SYN+ACK
)。 - 第三步:客戶端確認服務器“能發送”(服務器收到
ACK
)。
三次交互后,雙方確認彼此的發送和接收功能均正常。
- 第一步:客戶端確認服務器“能接收”(服務器收到
-
協商初始序列號:
客戶端和服務器通過前兩步交換各自的初始序列號(x
和y
),后續數據傳輸將基于這些序列號遞增,確保數據有序且可校驗(如通過序列號檢測丟包或重復數據)。
為什么需要三次握手,而不是兩次?
- 若僅用兩次握手,服務器在發送
SYN+ACK
后就認為連接已建立,但客戶端可能因網絡延遲等原因未收到該報文,此時服務器會一直等待客戶端發送數據,造成資源浪費。 - 三次握手的最后一步(客戶端發送
ACK
)確保客戶端確實收到了服務器的回應,避免服務器“單方面”建立無效連接,減少資源消耗。
總結
三次握手的本質是“雙向確認”:
客戶端請求連接 → 服務器確認并請求連接 → 客戶端確認
通過三次交互,雙方驗證了通信能力并協商了初始序列號,最終建立可靠的 TCP 連接,為后續數據傳輸奠定基礎。
四次揮手的實現
在 TCP 協議中,四次揮手(Four-Way Wavehand) 是關閉 TCP 連接的過程,用于確保雙方都已完成數據傳輸,并安全釋放連接資源。與三次握手建立連接不同,四次揮手需要四次交互,核心原因是 TCP 連接是全雙工的(雙方可同時發送數據),關閉連接時需各自獨立終止發送方向的數據流。
四次揮手的核心背景
TCP 連接是“全雙工”模式,即客戶端和服務器可以同時向對方發送數據。因此,關閉連接時需分兩步:
- 一方先終止向對方發送數據(關閉發送通道);
- 另一方確認并終止自己的發送通道。
這一過程需要四次交互來完成雙向確認。
四次揮手的具體步驟
假設客戶端主動發起關閉請求(實際中服務器也可主動發起),步驟如下:
第一步:客戶端 → 服務器(發送 FIN
報文)
-
客戶端行為:
客戶端完成數據發送后,向服務器發送FIN
報文(Finish,結束),表示“我已完成數據發送,請求關閉我向你發送數據的通道”。
報文中包含:- 標志位:
FIN = 1
(表示終止發送)。 - 序列號:
seq = u
(u
是客戶端已發送的最后一個字節的序列號 + 1,如客戶端最后發送的序列號是 1000,則u = 1001
)。
- 標志位:
-
客戶端狀態變化:
從“建立連接狀態(ESTABLISHED)”進入“終止等待 1 狀態(FIN-WAIT-1)”,等待服務器確認。
第二步:服務器 → 客戶端(發送 ACK
報文)
-
服務器行為:
服務器收到FIN
報文后,回復ACK
報文,表示“已收到你關閉發送通道的請求,我會處理剩余數據”。
報文中包含:- 標志位:
ACK = 1
(確認)。 - 序列號:
seq = v
(服務器當前的序列號,基于自身已發送的數據)。 - 確認號:
ack = u + 1
(表示“已收到序列號u
的FIN
報文,下一次期望接收u+1
”)。
- 標志位:
-
服務器狀態變化:
從“ESTABLISHED”進入“關閉等待狀態(CLOSE-WAIT)”,此時客戶端到服務器的發送通道已半關閉(客戶端不再發送數據,但服務器仍可向客戶端發送數據)。 -
客戶端狀態變化:
收到ACK
后,從“FIN-WAIT-1”進入“終止等待 2 狀態(FIN-WAIT-2)”,等待服務器發送自己的FIN
報文。
第三步:服務器 → 客戶端(發送 FIN
報文)
-
服務器行為:
服務器完成所有數據發送后,向客戶端發送FIN
報文,表示“我也已完成數據發送,請求關閉我向你發送數據的通道”。
報文中包含:- 標志位:
FIN = 1
、ACK = 1
(通常同時攜帶確認)。 - 序列號:
seq = w
(服務器最后發送的字節序列號 + 1,基于v
遞增)。 - 確認號:
ack = u + 1
(與第二步的確認號一致,因未收到新數據)。
- 標志位:
-
服務器狀態變化:
從“CLOSE-WAIT”進入“最后確認狀態(LAST-ACK)”,等待客戶端的最終確認。
第四步:客戶端 → 服務器(發送 ACK
報文)
-
客戶端行為:
客戶端收到服務器的FIN
報文后,回復ACK
報文,表示“已收到你關閉發送通道的請求,連接即將完全關閉”。
報文中包含:- 標志位:
ACK = 1
。 - 序列號:
seq = u + 1
(基于第一步的u
遞增)。 - 確認號:
ack = w + 1
(表示“已收到序列號w
的FIN
報文,下一次期望接收w+1
”)。
- 標志位:
-
客戶端狀態變化:
從“FIN-WAIT-2”進入“時間等待狀態(TIME-WAIT)”,并啟動一個 2MSL(Maximum Segment Lifetime,報文最大生存時間,通常為 2 分鐘) 的計時器。- 目的:確保服務器能收到最終的
ACK
報文(若服務器未收到,會重發FIN
,客戶端在 2MSL 內可再次回復)。 - 2MSL 后,客戶端進入“關閉狀態(CLOSED)”。
- 目的:確保服務器能收到最終的
-
服務器狀態變化:
收到ACK
后,從“LAST-ACK”直接進入“CLOSED”狀態,釋放連接資源。
四次揮手的核心目的
- 確保雙向數據傳輸完成:
雙方分別通過FIN
報文告知對方“自己的發送已結束”,通過ACK
確認對方已知曉,避免數據丟失。 - 避免連接關閉后的報文干擾:
客戶端的 2MSL 等待時間,確保網絡中殘留的舊報文(屬于當前連接)已過期,防止其干擾新連接(新連接可能使用相同的端口)。
為什么需要四次揮手,而不是三次?
- 三次握手時,服務器的
SYN
和ACK
可合并為一次報文(第二步SYN+ACK
),因為此時服務器無需處理未完成的數據發送。 - 四次揮手時,服務器收到客戶端的
FIN
后,可能還有未發送完的數據,因此需先回復ACK
確認(第二步),待數據發送完畢后再發送FIN
(第三步),無法合并為一次報文,因此需要四次交互。
總結
四次揮手是 TCP 全雙工連接關閉的必然過程:
客戶端請求關閉發送通道 → 服務器確認 → 服務器請求關閉發送通道 → 客戶端確認并等待
通過四次交互,雙方安全終止雙向數據流,并通過時間等待機制確保連接資源的徹底釋放,是 TCP 可靠性的重要體現。