位元組一面:說說TCP的三次握手

2022-08-28 18:00:41

上週有朋友去了位元組面試,問到了TCP三次握手的問題,當時回答的不是很好,對於三次握手的傳送的報文資訊都不太熟,本文主要做一下總結和記錄。

TCP全稱為Transmission Control Protocol(傳輸控制協定),是一種面向連線的、可靠的、基於位元組流的傳輸層通訊協定。TCP也是全雙工通訊協定,表示使用者端可以給伺服器端傳送訊息,伺服器端也可以向用戶端傳送訊息。

報文

TCP處於ISO七層模型的傳輸層,傳輸層的單位是報文,報文資訊如下:

Source port 和 Destination port

其中Source portDestination port分別代表傳送埠接收埠。兩個不同機器上的程序通訊,需要通過和IP協定中的IP標識唯一的程序。

Sequence number 和 Acknowledgment number

Sequence number表示序列號,表示要傳送資料的起始號,在下面的三次握手使用seq表示,Acknowledgment number表示確認號,返回確認號,表示訊息已經接收,返回下次要傳送的起始號。在下面的三次握手使用ackNum標識。

TCP flag

TCP flag表示TCP標誌位,主要介紹兩個ACKSYN

  • SYN同步序號,用於建立連線過程。
  • ACK確認序號標識,標識表示傳送資訊已確認接收。

Windows Size

TCP使用滑動視窗來實現流量控制,根據視窗大小,確認要傳送封包的個數。

TCP 三次握手

TCP三次握手,是指建立一個TCP連線時,需要使用者端和伺服器總共傳送3個包。三次握手的目的是連線服務指定埠,建立 TCP 連線,並確認連線雙方的序列號確認號,確認TCP視窗大小資訊。

三次握手詳解:

  • 第一次握手 SYN=1,seq=x
    • 使用者端傳送一個TCPSYN標誌位為1的包,指定使用者端連線的伺服器埠,初始序列號seqx。傳送完畢之後使用者端進入SYN_SEND
  • 第二次握手 SYN=1,ACK=1,seq=y,ACKnum=x+1
    • 伺服器發回確認包ACK應答。即SYN標誌位和ACK標誌位均為1。伺服器端傳送序列號seqy,同時將確認序號ackNum設定為使用者端的序列號seq+1ackNum表示要下次要傳送封包序列號的起始值。傳送完畢後,伺服器端進入SYN_SEND狀態。
  • 第三次握手 ACK=1,ACKnum=y+1
    • 使用者端再次傳送確認包ACK,ACK 標誌位為1,並且把伺服器發來的ackNum作為起始序號seq傳送給伺服器端,確認號ackNum為伺服器端傳送的序列號+1也就是y+1,放在確認欄位中傳送給對方,
    • 傳送完畢後,使用者端進入ESTABLISHED狀態,當伺服器端接收到這個包時,也進入ESTABLISHED狀態,開始資料傳輸。

wireshake 抓包

為了更好理解三次握手,使用wireshakej進行抓包。首先請求存取連結,TCP三次握手對應下面編號576364:

  • 第一步:192.168.5.150 ----> 47.98.202.133 [SYN] seq=0
  • 第二步:47.98.202.133 ----> 192.168.5.150 [SYN ACK] seq=0 ack=1
  • 第三步:192.168.3.150 ----> 47.98.202.133 [ACK] seq=1 ack=1

記憶口訣

那麼在面試的時候應該如何記憶三次握手的流程?三次握手是為了建立連線,其中主要是為了確認使用者端和伺服器端的序列號seq,那麼確認序列號就需要接收方返回序列號,來確保自己傳送的序列號能成功傳送。

  • 第一次握手和第二次握手確保使用者端的序列號,所以第一次傳送seq,第二次返回ack,當接收到返回資訊,表明確認了使用者端序列號。第一次和第二次都是建立連線過程,所以都帶有SYN標記位。而第二次返回號,所以第二次帶ACK標誌位。
  • 第一次傳送了序號seqx,返回確認號ackNumx+1,因為傳送消耗了一個序號,所以ackNum要加1
  • 第二次握手和第三次握手是為了確保伺服器端的序列號,伺服器端傳送序列號seq,使用者端返回確認號ackNum,值為seq+1。第二次握手要傳送序號和返回上一次的握手的確認號,所以第二次握手帶有SYNACK標誌位。並且要傳送序列號seq和確認號ackNum。第三次握手是確認伺服器端傳送序列號,所以帶有標誌位ACK,返回確認號ackNum

為啥 TCP 需要三次握手,不是兩次,四次

TCP三次握手是為了確認雙方的序列號,這就像一個傳送—應答機制,使用者端發序列號,伺服器端返回確認號,此時確認了使用者端的序列號。如果是兩次握手,只能確認使用者端的序列號,無法確認伺服器端的序列號。三次握手是確認兩個序列號最小的連線次數。四次也可以,但是沒有必要,需要減少握手的次數,加快連線速度。

總結

  • 本文先介紹了報文頭資訊,三次握手主要用到了:
    • 序列號seq,確認號ackNum
    • TCP標記位,SYN同步序號,表示建立連線過程。ACK確認序號標識,標識表示傳送資訊已確認接收
  • 三次握手詳解:
    • 第一次握手,使用者端傳送帶有SYN標記位的包,帶有初始化序列號x,傳送完畢使用者端進入SYN_SEND狀態。
    • 第二次握手,伺服器端返回應答標記位ACK,並返回確認號ackNumx+1,x+1表示傳送消耗了一個序列號。返回了確認號表示確認了使用者端序列號。伺服器端也要傳送序列號y,所以也要帶有SYN的標記位。
    • 第三次握手使用者端傳送確認包ackNumy+1,所以帶確認序號標誌ACK。建立連線,傳送序號x+1,開始傳輸資料。

參考

TCP協定