12.TCP資料包結構以及三次握手(圖解)
TCP(Transmission Control Protocol,傳輸控制協議)是一種面向連線的、可靠的、基於位元組流的通訊協議,資料在傳輸前要建立連線,傳輸完畢後還要斷開連線。
客戶端在收發資料前要使用 connect() 函式和伺服器建立連線。建立連線的目的是保證IP地址、埠、物理鏈路等正確無誤,為資料的傳輸開闢通道。
TCP建立連線時要傳輸三個資料包,俗稱三次握手(Three-way Handshaking)。可以形象的比喻為下面的對話:
[Shake 1] 套接字A:“你好,套接字B,我這裡有資料要傳送給你,建立連線吧。”
[Shake 2] 套接字B:“好的,我這邊已準備就緒。已經給你的Ack+1”
[Shake 3] 套接字A:“謝謝你受理我的請求,我又給Ack+1,發你了。”
TCP資料包結構
我們先來看一下TCP資料包的結構:

帶陰影的幾個欄位需要重點說明一下:
序號:Seq(Sequence Number)序號佔32位,用來標識從計算機A傳送到計算機B的資料包的序號,計算機傳送資料時對此進行標記。
確認號:Ack(Acknowledge Number)確認號佔32位,客戶端和伺服器端都可以傳送,Ack = Seq + 1。
標誌位:每個標誌位佔用1Bit,共有6個,分別為 URG、ACK、PSH、RST、SYN、FIN,具體含義如下:
URG:緊急指標(urgent pointer)有效。
ACK:確認序號有效。
PSH:接收方應該儘快將這個報文交給應用層。
RST:重置連線。
SYN:建立一個新連線。
FIN:斷開一個連線。
對英文字母縮寫的總結:Seq 是 Sequence 的縮寫,表示序列;Ack(ACK) 是 Acknowledge 的縮寫,表示確認;SYN 是 Synchronous 的縮寫,願意是“同步的”,這裡表示建立同步連線;FIN 是 Finish 的縮寫,表示完成。
連線的建立(三次握手)
使用 connect() 建立連線時,客戶端和伺服器端會相互傳送三個資料包,請看下圖:

客戶端呼叫 socket() 函式建立套接字後,因為沒有建立連線,所以套接字處於CLOSED狀態;伺服器端呼叫 listen() 函式後,套接字進入LISTEN狀態,開始監聽客戶端請求。
這個時候,客戶端開始發起請求:
當客戶端呼叫 connect() 函式後,TCP協議會組建一個資料包,並設定 SYN 標誌位,表示該資料包是用來建立同步連線的。同時生成一個隨機數字 1000,填充“序號(Seq)”欄位,表示該資料包的序號。完成這些工作,開始向伺服器端傳送資料包,客戶端就進入了SYN-SEND狀態。
伺服器端收到資料包,檢測到已經設定了 SYN 標誌位,就知道這是客戶端發來的建立連線的“請求包”。伺服器端也會組建一個資料包,並設定 SYN 和 ACK 標誌位,SYN 表示該資料包用來建立連線,ACK 用來確認收到了剛才客戶端傳送的資料包。
伺服器生成一個隨機數 2000,填充“序號(Seq)”欄位。2000 和客戶端資料包沒有關係。
伺服器將客戶端資料包序號(1000)加1,得到1001,並用這個數字填充“確認號(Ack)”欄位。
伺服器將資料包發出,進入SYN-RECV狀態。客戶端收到資料包,檢測到已經設定了 SYN 和 ACK 標誌位,就知道這是伺服器發來的“確認包”。客戶端會檢測“確認號(Ack)”欄位,看它的值是否為 1000+1,如果是就說明連線建立成功。
接下來,客戶端會繼續組建資料包,並設定 ACK 標誌位,表示客戶端正確接收了伺服器發來的“確認包”。同時,將剛才伺服器發來的資料包序號(2000)加1,得到 2001,並用這個數字來填充“確認號(Ack)”欄位。
客戶端將資料包發出,進入ESTABLISED狀態,表示連線已經成功建立。伺服器端收到資料包,檢測到已經設定了 ACK 標誌位,就知道這是客戶端發來的“確認包”。伺服器會檢測“確認號(Ack)”欄位,看它的值是否為 2000+1,如果是就說明連線建立成功,伺服器進入ESTABLISED狀態。
至此,客戶端和伺服器都進入了ESTABLISED狀態,連線建立成功,接下來就可以收發資料了。
最後的說明
三次握手的關鍵是要確認對方收到了自己的資料包,這個目標就是通過“確認號(Ack)”欄位實現的。計算機會記錄下自己傳送的資料包序號 Seq,待收到對方的資料包後,檢測“確認號(Ack)”欄位,看Ack = Seq + 1是否成立,如果成立說明對方正確收到了自己的資料包。
相關文章
- 圖解Java常用資料結構圖解Java資料結構
- 三次握手
- TCP三次握手、四次揮手概念圖詳解TCP
- 圖解TCP的三次握手和四次揮手圖解TCP
- WireShark抓包分析以及對TCP/IP三次握手與四次揮手的分析TCP
- 資料結構 - 圖資料結構
- Http協議詳解之三次握手HTTP協議
- OpenVPN 協議解析-握手資料包分析協議
- TCP 三次握手原理以及半連線和全連線TCP
- 【資料結構——圖和圖的儲存結構】資料結構
- TCP 的 三次握手 四次握手TCP
- 資料結構之圖資料結構
- 資料結構:圖(Graph)資料結構
- 前端系列-三次握手前端
- TCP三次握手原理TCP
- 資料結構與演算法-圖解版資料結構演算法圖解
- 圖解:Java 中的資料結構及原理圖解Java資料結構
- tcpdump抓包mysql建聯驗證TCP的三次握手TCPMySql
- Wireshark抓包分析TCP“三次握手,四次揮手”TCP
- TCP 三次握手和四次揮手圖解(有限狀態機)TCP圖解
- (圖文並茂,權威最詳細)Wireshark抓包分析 TCP三次握手/四次揮手詳解TCP
- Redis 概念以及底層資料結構Redis資料結構
- 【Immutable.js】可持久化資料結構以及結構分享JS持久化資料結構
- js資料結構--圖(graph)JS資料結構
- JS Graph (圖-資料結構)JS資料結構
- 實戰:tcpdump抓包分析三次握手四次揮手TCP
- 圖解vsan儲存結構/資料恢復方法圖解資料恢復
- 圖解Redis之資料結構篇——壓縮列表圖解Redis資料結構
- 圖解Redis之資料結構篇——跳躍表圖解Redis資料結構
- 圖解Redis之資料結構篇——整數集合圖解Redis資料結構
- 瀏覽器三次握手瀏覽器
- 綜合解讀TCP為什麼三次握手TCP
- 資料結構學習總結--圖資料結構
- leetcode演算法資料結構題解---資料結構LeetCode演算法資料結構
- 資料結構與演算法:圖形結構資料結構演算法
- 三次握手的誤解與錯誤類比 (RFC 解讀)
- 重學資料結構(七、圖)資料結構
- 詳解TCP一:三次握手、四次揮手TCP
- TCP的三次握手過程TCP