在軟體中,handshake 表示一個信號 (signal),表示 2 台設備或程式要進行身份驗證 (authenticate) or 合作 (coordinate) (詳見 Wiki - Handshake (computing) - Wikipedia )
當我們要握手時,身為 Client 的我們就是希望能與 Server 交互合作,那我們就要先驗明彼此的身份,並確定雙方能有效地交換資料和溝通
有三次握手的過程,分別是:
1st handshake:
Client 想測試 Server 的接收能力
2nd handshake:
Server 讓 Client 知道:我能成功收到且正確的讀取你的訊息
Server 想測試 Client 的接收能力
3rd handshake:
Client 讓 Server 知道:我能成功收到且正確的讀取你的訊息
這就好比你在路上跟一個女生要了 Line,然後,然後想測試看看你傳訊息「你好」給她,她能不能正常回你,不是用機器人自動回覆「我要去洗澡喔」或是「你幫我去某某某網站幫我衝人氣好嗎?」,然後你也要回傳訊息給她,讓她知道你可以正常地跟她溝通
真實世界 | TCP handshake | |
---|---|---|
1st | 你發訊息「安安,我是 Jason,妳好嗎?」給她,測試她會不會回你 line | Client 想測試 Server 的接收能力 |
2nd | 她說「安安啊,我是 Ketty,你好嗎?」給你,表示她有讀懂你的訊息,且正常回你 | Server 讓 Client 知道,我能成功收到且正確的讀取你的訊息,並想測試 Client 的接收能力 |
3rd | 你說「我很好,謝謝」讓他知道你有看懂她的訊息 | Client 讓 Server 知道,我能成功收到且正確的讀取你的訊息 |
1st handshake 有 1 個目的:
Clinet 發送 SYN segment 給 Server,希望建立連結,並測試 Server 的接收能力
SYN : Synchronize Sequence Numbers,目的為確認雙方 sequence number 相同的資料
傳送的資料:
SYN
segment,其 seq num = xClient 狀態:CLOSED -> SYN_SENT
Server 狀態:LISTEN -> SYN_RCVD
2nd handshake 有 2 個目的:
Server 接收到 Client 資料,成功讀取後,會傳送另一包資料給 Client,告訴 Client 我成功收到你的資料,”成功“ 在這有 2 個含義:
故 Server 會對應 Client 傳送的資料回傳相關的結果,這裡回傳 ack = seq + 1
傳送的資料:
ACK
segment,其 ack num = x + 1
跟 1st handshake 的過程一樣,但傳送不同的 sequenceNumber
傳送的資料:
SYN
segment,其 seq num = yClient 狀態:SYN_SENT -> ESTABLISHED
Server 狀態:SYN_RCVD
3rd handshake 有 1 個目的:
傳送的資料:
ACK
segment, 其 ack num = y + 1Client 狀態: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
重試的過程:
即當 Server 沒有回傳 ACK,Client 會等待 2^n s 後重發,最多重發 6 次,若最後仍沒收到,就會終止傳輸的建立,全部的等待時間為:
1 + 2 + 4 + 8 + 16 + 32 = 127
故若等了 2 分鐘還是無法建立成功,就會終止