網路與通訊端

三向交握與連線拆除(three-way handshake and teardown)

兩個人能通電話之前,有一個小小的儀式:一方說「喂?」,另一方回「喂,我聽得到你」,第一方再確認「太好了,我也聽得到你」。只有在這之後他們才開始講話。TCP 做的正是同樣這支舞,稱為三向交握,用來建立連線,好讓雙方在任何真正的資料流動之前,先同意彼此都聽得到對方。

這三步使用帶旗標的小型控制封包。客戶端送出一個帶 SYN 旗標的封包(「我想開始,這是我的起始序號」)。伺服器以 SYN-ACK 回覆(「我確認收到你的,這是我的」)。客戶端再以 ACK 回覆(「我確認收到你的」)。三則訊息,故稱三向。如今雙方都已確認彼此能送能收,並就起始序號達成一致,好讓他們能偵測遺失與順序。這正是客戶端的 connect() 所觸發的事,也是伺服器在它完成後交給你的 accept() 結果。拆除連線則是類似的禮貌交換:每一方送出一個 FIN(「我傳完了」),另一方加以 ACK,使兩個方向都乾淨地關閉,常被畫成四步關閉。

為何重要:這正是為什麼 TCP 被稱為連線導向——在你的資料移動之前,確實有一段建立連線的對話,耗費一次來回,這也是 TCP 比「送了就不管」的 UDP 延遲更高的部分原因。你幾乎從不自己寫交握;核心會在 connect() 與 accept() 裡頭替你完成。但知道它存在,能解釋為何 connect() 會花時間、為何被拒絕的連線會很快失敗(伺服器以重置而非 SYN-ACK 回應),以及為何關閉一個通訊端不只是把它忘掉而已。

客戶端 -> 伺服器:SYN。伺服器 -> 客戶端:SYN-ACK。客戶端 -> 伺服器:ACK。這三則訊息之後連線即告建立,位元組便可流動。要關閉時:每一方送出 FIN 並收回一個 ACK。

三個小封包在任何資料送出之前,先確認連線存在。

交握是由核心完成的,不是你的程式碼——你只透過 connect()/accept() 的成功或失敗看到它的效果。它耗費一次網路來回,這是連線延遲中實實在在的一部分。

又稱
TCP handshakeSYN/SYN-ACK/ACKconnection setup and teardown三次握手