Skip to main content

[TCP] 2. 為什麼要知道 TCP 三次握手?三次握手過程為何?

為什麼知道 TCP handshake 很重要?

  • 前端面試必考
  • 知道 TCP handshake 過程很複雜,每次建立所要花的時間和代價都很大,可以的話盡量減少 TCP handshake,以減少 network request 時間

為什麼要握手?

在軟體中,handshake 表示一個信號 (signal),表示 2 台設備或程式要進行身份驗證 (authenticate) or 合作 (coordinate) (詳見 Wiki - Handshake (computing) - Wikipedia )

當我們要握手時,身為 Client 的我們就是希望能與 Server 交互合作,那我們就要先驗明彼此的身份,並確定雙方能有效地交換資料和溝通


三次握手的詳細過程是什麼?

https://ithelp.ithome.com.tw/upload/images/20231007/20148944ds1a2z5gA1.png

有三次握手的過程,分別是:

nth 握手目的
1stClient 想測試 Server 的接收能力
2nd
  • Server 讓 Client 知道:我能成功收到且正確的讀取你的訊息
  • Server 想測試 Client 的接收能力
  • 3rdClient 讓 Server 知道:我能成功收到且正確的讀取你的訊息



    比喻

    這就好比你在路上跟一個女生要了 Line,然後,然後想測試看看你傳訊息「你好」給她,她能不能正常回你, 而不是用機器人自動回覆「我要去洗澡喔」或是「你幫我去某某某網站幫我衝人氣好嗎?」,然後你也要回傳訊息給她,讓她知道你可以正常地跟她溝通


    真實世界TCP handshake
    1st你發訊息「安安,我是 Jason,妳好嗎?」給她,測試她會不會回你 lineClient 想測試 Server 的接收能力
    2nd她說「安安啊,我是 Ketty,你好嗎?」給你,表示她有讀懂你的訊息,且正常回你Server 讓 Client 知道,我能成功收到且正確的讀取你的訊息,並想測試 Client 的接收能力
    3rd你說「我很好,謝謝」讓他知道你有看懂她的訊息Client 讓 Server 知道,我能成功收到且正確的讀取你的訊息


    1st handshake

    1st handshake 有 1 個目的:

    Client 想測試 Server 的接收能力

    Clinet 發送 SYN segment 給 Server,希望建立連結,並測試 Server 的接收能力


    SYN 是什麼?

    Synchronize Sequence Numbers,目的為確認雙方 sequence number 相同的資料



    傳送的資料:

    • 1 SYN segment,其 seq num = x
    Client 狀態:CLOSED -> SYN_SENT
    Server 狀態:LISTEN -> SYN_RCVD


    2nd handshake

    2nd handshake 有 2 個目的:

    1. Server 讓 Client 知道:我能成功收到且正確的讀取你的訊息
    2. Server 想測試 Client 的接收能力

    1. Server 讓 Client 知道:我能成功收到且正確的讀取你的訊息

    Server 接收到 Client 資料,成功讀取後,會傳送另一包資料給 Client,告訴 Client 我成功收到你的資料,”成功“ 在這有 2 個含義:

    • 我 ”收到“ Client 的資料
    • 我 "正確的讀取" Client 的資料

    故 Server 會對應 Client 傳送的資料回傳相關的結果,這裡回傳 ack = seq + 1

    傳送的資料:

    • 1 ACK segment,其 ack num = x + 1

    2. Server 想測試 Client 的接收能力

    跟 1st handshake 的過程一樣,但傳送不同的 sequenceNumber

    傳送的資料:

    • 1 SYN segment,其 seq num = y
    Client 狀態:SYN_SENT -> ESTABLISHED
    Server 狀態:SYN_RCVD

    3rd handshake

    3rd handshake 有 1 個目的:

    Client 讓 Server 知道:我能成功收到且正確的讀取你的訊息

    傳送的資料:

    • 1 ACK segment, 其 ack num = y + 1
    Client 狀態:ESTABLISHED
    Server 狀態:SYN_RCVD -> ESTABLISHED



    這 3 次 handshake 後,Client 和 Server 就能保證彼此的接收能力都是正常的了



    其他問題


    為什麼要三次握手,兩次不行嗎?

    如果少掉 3rd handshake,Server 就無法確認 Client 的接收能力是正常的, 那就無法穩定的傳輸,TCP protocal 的目的也就沒達成


    握手沒成功會怎樣嗎?

    若握手沒成功,當 Client 發現 Server 沒有回傳 ACK segment, 就會重發 (retransmission) 重發的次數由 tcp_syn_retries 參數決定,默認是 6 次

    net.ipv4.tcp_syn_retries = 6

    重試的過程:

    • step 1:1s 後 Server 沒回傳 ACK,Client 重傳 SYN
    • step 2:若 Client 還是沒收到 ACK,重複步驟 1,但等待時間為 2s
    • step 3:若 Client 還是沒收到 ACK,重複步驟 1,但等待時間為 4s
    • step 4:若 Client 還是沒收到 ACK,重複步驟 1,但等待時間為 8s
    • step 5:若 Client 還是沒收到 ACK,重複步驟 1,但等待時間為 16s
    • step 6:若 Client 還是沒收到 ACK,重複步驟 1,但等待時間為 32s
    • setp 7:若 Client 還是沒收到 ACK,終止 3 way handshake

    即當 Server 沒有回傳 ACK,Client 會等待 2^n s 後重發,最多重發 6 次,若最後仍沒收到,就會終止傳輸的建立,全部的等待時間為:

    1 + 2 + 4 + 8 + 16 + 32 = 127

    故若等了 2 分鐘還是無法建立成功,就會終止


    結論

    • 知道為什麼要建立 TCP handshake,是為了雙方知道彼此能正常接收和傳輸,且三次是最精簡的步驟
    • 知道 Server 和 Client 怎麼確保對方的接收和傳輸的流程
    • 知道握手過程失敗,會有 retransmission 的行為,持續 2 分鐘,若還是沒有成功就會終止


    參考資訊