位元組一面:說說TCP的三次握手
- 2022 年 8 月 28 日
- 筆記
上周有朋友去了位元組面試,問到了
TCP
三次握手的問題,當時回答的不是很好,對於三次握手的發送的報文資訊都不太熟,本文主要做一下總結和記錄。
TCP
全稱為Transmission Control Protocol
(傳輸控制協議),是一種面向連接的、可靠的、基於位元組流
的傳輸層通訊協議。TCP
也是全雙工通訊協議,表示客戶端可以給服務端發送消息,服務端也可以向客戶端發送消息。
報文
TCP
處於ISO
七層模型的傳輸層
,傳輸層的單位是報文
,報文資訊如下:
Source port 和 Destination port
其中Source port
和Destination port
分別代表發送埠
和接收埠
。兩個不同機器上的進程通訊,需要通過埠
和IP協議中的IP
標識唯一的進程。
Sequence number 和 Acknowledgment number
Sequence number
表示序列號
,表示要發送數據的起始號,在下面的三次握手使用seq
表示,Acknowledgment number
表示確認號
,返回確認號,表示消息已經接收,返回下次要發送的起始號。在下面的三次握手使用ackNum
標識。
TCP flag
TCP flag
表示TCP
標誌位,主要介紹兩個ACK
和SYN
:
SYN
同步序號,用於建立連接過程。ACK
確認序號標識,標識表示發送資訊已確認接收。
Windows Size
TCP
使用滑動窗口
來實現流量控制
,根據窗口大小,確認要發送數據包的個數。
TCP 三次握手
TCP
三次握手,是指建立一個TCP
連接時,需要客戶端和伺服器總共發送3
個包。三次握手的目的是連接服務指定埠,建立 TCP 連接,並確認
連接雙方的序列號
和確認號
,確認TCP
窗口大小資訊。
三次握手詳解:
- 第一次握手
SYN=1,seq=x
- 客戶端發送一個
TCP
的SYN
標誌位為1
的包,指定客戶端連接的伺服器埠,初始序列號seq
為x
。發送完畢之後客戶端進入SYN_SEND
。
- 客戶端發送一個
- 第二次握手
SYN=1,ACK=1,seq=y,ACKnum=x+1
- 伺服器發回確認包
ACK
應答。即SYN
標誌位和ACK
標誌位均為1。伺服器端發送序列號seq
為y
,同時將確認序號ackNum
設置為客戶端的序列號seq+1
,ackNum
表示要下次要發送數據包序列號的起始值。發送完畢後,服務端進入SYN_SEND
狀態。
- 伺服器發回確認包
- 第三次握手
ACK=1,ACKnum=y+1
- 客戶端再次發送確認包
ACK
,ACK 標誌位為1
,並且把伺服器發來的ackNum
作為起始序號seq
發送給服務端,確認號ackNum
為服務端發送的序列號+1
也就是y+1
,放在確認欄位中發送給對方, - 發送完畢後,客戶端進入
ESTABLISHED
狀態,當伺服器端接收到這個包時,也進入ESTABLISHED
狀態,開始數據傳輸。
- 客戶端再次發送確認包
wireshake 抓包
為了更好理解三次握手,使用wireshakej進行抓包。首先請求訪問鏈接,TCP
三次握手對應下面編號57
、63
、64
:
- 第一步:
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
標誌位。 - 第一次發送了序號
seq
為x
,返回確認號ackNum
為x+1
,因為發送消耗了一個序號,所以ackNum
要加1
。 - 第二次握手和第三次握手是為了確保服務端的序列號,服務端發送序列號
seq
,客戶端返回確認號ackNum
,值為seq+1
。第二次握手要發送序號和返回上一次的握手的確認號,所以第二次握手帶有SYN
和ACK
標誌位。並且要發送序列號seq
和確認號ackNum
。第三次握手是確認服務端發送序列號,所以帶有標誌位ACK
,返回確認號ackNum
。
為啥 TCP 需要三次握手,不是兩次,四次
TCP
三次握手是為了確認雙方的序列號,這就像一個發送—應答
機制,客戶端發序列號,服務端返回確認號,此時確認了客戶端的序列號。如果是兩次握手,只能確認客戶端的序列號,無法確認服務端的序列號。三次握手是確認兩個序列號最小的連接次數。四次也可以,但是沒有必要,需要減少握手的次數,加快連接速度。
總結
- 本文先介紹了報文頭資訊,三次握手主要用到了:
- 序列號
seq
,確認號ackNum
。 TCP
標記位,SYN
同步序號,表示建立連接過程。ACK
確認序號標識,標識表示發送資訊已確認接收
- 序列號
- 三次握手詳解:
- 第一次握手,客戶端發送帶有
SYN
標記位的包,帶有初始化序列號x
,發送完畢客戶端進入SYN_SEND
狀態。 - 第二次握手,服務端返回應答標記位
ACK
,並返回確認號ackNum
為x+1
,x+1
表示發送消耗了一個序列號。返回了確認號表示確認
了客戶端序列號。服務端也要發送序列號y
,所以也要帶有SYN
的標記位。 - 第三次握手客戶端發送確認包
ackNum
為y+1
,所以帶確認序號標誌ACK
。建立連接,發送序號x+1
,開始傳輸數據。
- 第一次握手,客戶端發送帶有