TCP為什麼需要握手

一、TCP握手流程

二、為什麼不是4次握手

TCP的每次請求都是成對的,原則上應該是四次

  1. 【Client to Server】第一次SYN,seq=x
  2. 【Server to Client】第二次ACK,seq=y,ack=x+1(沒有攜帶數據的ACK不消耗序列號)
  3. 【Server to Client】第三次SYN,seq=y,
  4. 【Client to Server】第四次ACK,seq=x+1,ack=y+1.

可以看出第二次和第三次都是Server to Client,且他們之間沒有任何事件發生,所以可以合併,不是四次的原因是2,3步驟合併,增加效率。

三、為什麼需要握手(為什麼需要三《」四「》次握手)

要回答為什麼先看看什麼是TCP鏈接。ref //tools.ietf.org/html/rfc793

    The reliability and flow control mechanisms described above requirez
    that TCPs initialize and maintain certain status information for
    each data stream.  The combination of this information, including
    sockets, sequence numbers, and window sizes, is called a connection.
    Each connection is uniquely specified by a pair of sockets
    identifying its two sides.

為了保證可靠性傳輸,TCP需要兩邊維護socket,序列號,和窗口大小(流量控制用),握手就是為了在數據開始傳輸前讓客戶端和伺服器準確無誤的交換上述資訊。

需要握手的原因:

  1. 阻止已經失效的歷史請求的初始化【謝希仁】
  2. 只有通過三次握手才能交換序列號

3.1 阻止已經失效的歷史請求的初始化

 ref://tools.ietf.org/html/rfc793

The principle reason for the three-way handshake is to 
prevent old duplicate connection initiations from causing confusion.

假如只有兩次握手

 

假如服務端在ack以後就建立了鏈接,當有延遲的數據在鏈接關閉後到達服務端,

  • 服務端不知道這是舊鏈接,直接建立返回ack,且建立了鏈接。
  • 因為上一次鏈接已經關閉,客戶端不認識這個ack,直接丟棄。

這樣會導致服務端資源被這種失效的鏈接給浪費。

3.2 只有通過三次握手才能交換序列號

序列號是可靠性傳輸的根本,通過序列號,接收方可以去重,可以保證TCP流按照順序最終被接受。

初始序列號是隨機生成的(為了安全),所以在鏈接建立之初需要雙方通過SYN來告知對方自己的初始序列號。

同時每一個發出去的序列號,都需要一個接收方的ACK,來告訴發送方:我已經收到了–可靠性保證

所以兩次握手不行:服務端的SYN,沒有辦法ACK。

由於第二次和第三次可以合併,所以最終把邏輯上的四次握手變成了三次。