TCP 爲什麼三次握手而不是兩次握手(正解版)

原文鏈接:https://blog.csdn.net/lengxiao1993/article/details/82771768

參考文章

Why do we need a 3-way handshake? Why not just 2-way

大部分網絡博客的錯誤解讀

首先需要聲明的是, 百度搜索到的大部分網絡博客關於這個問題的解答都是不清晰或者不準確的。 討論這個問題的大部分博客都會引用《計算機網絡》的內容:

  1. 防止已失效的連接請求又傳送到服務器端,因而產生錯誤

不幸的是, 這種解釋是不準確的, TCP 採用三次握手的原因其實非常簡單, 遠沒有大部分博客所描述的那樣雲山霧繞。

這裏先給出結論:

  • 爲了實現可靠數據傳輸, TCP 協議的通信雙方, 都必須維護一個序列號, 以標識發送出去的數據包中, 哪些是已經被對方收到的。 三次握手的過程即是通信雙方相互告知序列號起始值, 並確認對方已經收到了序列號起始值的必經步驟
  • 如果只是兩次握手, 至多隻有連接發起方的起始序列號能被確認, 另一方選擇的序列號則得不到確認

先修知識

TCP 通信流程

TCP 的通信流程
在這裏插入圖片描述

上圖中的每一個箭頭都代表着一次 TCP數據包的發送

  • 需要注意的是, 上圖中出現的 ACK = x +1 的寫法很容易讓人誤以爲數據包中的 ACK 域的數據值被填成了 y+1 。 ACK = x+1 的實際含義是:
    • TCP 包的 ACK 標誌位(1 bit) 被置成了 1
    • TCP 包的確認號(acknowledgement number ) 的值爲 x+1
  • 類似的, TCP 數據包中的 SYN 標誌位, 也容易與序號(sequence number) 混淆, 這點需要讀者注意

TCP 數據包結構圖
TCP包結構圖

爲什麼 TCP 需要握手這個操作

在解答爲什麼 TCP 需要三次握手, 而不是兩次之前, 首先需要回答的問題是:

  • 爲什麼需要握手這個操作, 能不能不握手?

如果讀者對比一下 UDP 的通信流程和 TCP 的通信流程, 可以發現, 在 UDP 協議中, 是沒有握手這個操作的。
在這裏插入圖片描述

這裏就引出了 TCP 與 UDP 的一個基本區別, TCP 是可靠通信協議, 而 UDP 是不可靠通信協議。

  • TCP 的可靠性含義: 接收方收到的數據是完整, 有序, 無差錯的。
  • UDP 不可靠性含義: 接收方接收到的數據可能存在部分丟失, 順序也不一定能保證。

UDP 和 TCP 協議都是基於同樣的互聯網基礎設施, 且都基於 IP 協議實現, 互聯網基礎設施中對於數據包的發送過程是會發生丟包現象的, 爲什麼 TCP 就可以實現可靠傳輸, 而 UDP 不行?

TCP 協議爲了實現可靠傳輸, 通信雙方需要判斷自己已經發送的數據包是否都被接收方收到, 如果沒收到, 就需要重發。 爲了實現這個需求, 很自然地就會引出序號(sequence number) 和 確認號(acknowledgement number) 的使用。

發送方在發送數據包(假設大小爲 10 byte)時, 同時送上一個序號( 假設爲 500),那麼接收方收到這個數據包以後, 就可以回覆一個確認號(510 = 500 + 10) 告訴發送方 “我已經收到了你的數據包, 你可以發送下一個數據包, 序號從 510 開始” 。

這樣發送方就可以知道哪些數據被接收到,哪些數據沒被接收到, 需要重發。

爲什麼需要三次握手,而非兩次

正如上文所描述的,爲了實現可靠傳輸,發送方和接收方始終需要同步( SYNchronize )序號。 需要注意的是, 序號並不是從 0 開始的, 而是由發送方隨機選擇的初始序列號 ( Initial Sequence Number, ISN )開始 。 由於 TCP 是一個雙向通信協議, 通信雙方都有能力發送信息, 並接收響應。 因此, 通信雙方都需要隨機產生一個初始的序列號, 並且把這個起始值告訴對方。

於是, 這個過程就變成了下面這樣。
在這裏插入圖片描述

下面這個流程圖描述的和上面一樣, 但是更加清楚的展示了 TCP 數據包標誌位, 以及數據域的命名來源

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章