TCP (Transmission Control Protocol),中文翻譯為傳輸控制協定,是連接導向的協定,為應用程式提供可靠、有序的位元組流服務,他的可靠性包括偵測封包遺失(透過序號)和錯誤(透過每段校驗和),以及透過重傳進行修正,同時也透過給予封包序號在收到訊息時確認封包順序是否正確。由RFC 793定義,後來被RFC 9293廢棄,因此本文主要參考資料為 RFC 9293。
從上圖來看,主要可以分成以下三個流程:
<SEQ=100><CTL=SYN>
,表示它將使用從100開始的序號,此時 client 端進入等待回覆的狀態,而 server 端接收到訊息並準備回應。<SEQ=300><ACK=101><CTL=SYN,ACK>
,而此時 sever 端期待收到序號101,ACK 的值為 SEQ 值加 1 ,表示確認序號100的 SYN 。<SEQ=101><ACK=301><CTL=ACK>
,ACK 值為 301,為 server 端的SEQ值加1,表示已確認 server 端 的 SYN。此時雙方已經成功建立連結,此時就可以開始傳輸資料拉!以上可能聽起來有點霧煞煞,搭配以下生活化場景應該會比較好理解:
在RFC 9293中有提到:
The principal reason for the three-way handshake is to prevent old duplicate connection initiations from causing confusion.To deal with this, a special control message, reset, is specified.
三次握手的主要目的是防止舊的重複連接請求引起混亂。為了解決這個問題,TCP 定義了一個特殊的控制消息,稱為 重置 (reset, RST)。
在網絡中,可能會有之前發送的連接請求(例如之前的 SYN 消息)因延遲或其他原因重複到達 server 端。如果不處理這種情況,這些舊的請求可能會干擾到新的連接,導致混亂。不採用三次握手的話,只要 server 端發出確認,就建立新的連接了,此時 client 端忽略 server 端發來的確認,也不發送數據,則 server 端會一直等待 client 端發送數據,浪費資源。
因此 server 端在回傳 client 端第一次發送的SYN 時,其中的 ACK 值為SEQ 值加1
,使 client 端能夠確認這個連線請求是不是已經失效的歷史連線請求,而當 client 端發現是失效連線時,就會透過傳送 RST 訊息給 server 端以中止連線。
今天有較為深入的分享關於 TCP 協定連線前的三次握手的內容,以及為什麼需要三次握手,我的理解可能不一定很正確,如果有誤都歡迎留言討論~
維基百科
RFC 9293
TCP/IP 協議中的三次握手與四次握手
面試官,不要再問我三次握手和四次揮手