TCP(傳輸控制協議)的三次握手是建立可靠連線的關鍵步驟,其設計目的是確保通訊雙方都準備好,並且避免重複的連線初始化。三次握手並不是隨意設定的,而是有其重要的技術理由。
1. 防止重複的連線初始化
假設只使用兩次握手,會存在以下問題:
- 舊的重複SYN包問題:如果網路中的一箇舊的SYN包(因為網路延遲等原因)突然到達伺服器,伺服器會誤以為是一個新的連線請求。如果沒有第三次握手,伺服器會直接接受這個舊的請求並建立連線,但客戶端實際上並沒有傳送新的請求。這會導致資源浪費和連線狀態混亂。
2. 確認雙方的接收和傳送能力
三次握手確保了雙方的傳送和接收能力:
- 第一次握手(SYN):客戶端告訴伺服器它希望建立連線,併傳送初始序列號。
- 第二次握手(SYN-ACK):伺服器收到請求並回應,同時傳送自己的初始序列號,表示自己已經準備好接收資料。
- 第三次握手(ACK):客戶端確認伺服器的回應,同時確認自己可以接收伺服器的資料。
3. 避免資源浪費
如果沒有三次握手的確認步驟,伺服器會在每次收到SYN請求後直接分配資源(如快取和連線控制塊)。但由於客戶端未必真正準備好,這些資源可能會被浪費。三次握手確保只有在雙方都確認可以通訊的情況下才會分配資源。
兩次握手的問題示例
假設使用兩次握手:
- 第一次握手(SYN):客戶端傳送SYN包,伺服器接收並回應SYN-ACK。
- 第二次握手(SYN-ACK):伺服器傳送SYN-ACK包,認為連線已建立。
在這種情況下,如果客戶端由於某種原因沒有接收到SYN-ACK包(如網路丟包),伺服器認為連線已經建立並開始等待客戶端的資料,但客戶端並沒有建立連線。這會導致伺服器資源被浪費,最終可能導致拒絕服務攻擊(DoS)。
sequenceDiagram participant Client as 客戶端 participant Server as 伺服器 Client->>Server: SYN (序列號X) Server-->>Client: SYN-ACK (序列號Y, 確認號X+1) Client->>Server: ACK (確認號Y+1)