本文主要介紹 TCP 的握手連接與斷開,這里我以“金庸夢“游戲的客戶端連接服務器(10.1.230.41)、斷開服務器為例,用wireshark抓包分析 TCP 協議的三次握手連接、四次握手斷開,與計算機網絡原理進行驗證;用Fiddler抓包,分析驗證一個 HTTPS 網站的 TCP 連接過程。
一、TCP 協議的連接與斷開
TCP/IP(Transmission Control Protocol/Internet Protocol) 即傳輸控制協議/網間協議,是一種面向連接(連接導向)的、可靠的、基於字節流的運輸層(Transport layer)通信協議,由IETF的RFC 793說明(specified)。在簡化的計算機網絡OSI模型中,它完成第四層傳輸層所指定的功能,UDP是同一層內另一個重要的傳輸協議。
下圖是一個 TCP 包頭的結構,這部分主要分析 TCP 協議的三次握手連接和四次握手斷開,着重注意 ACK 、 SYN 、FIN 。

- URG:緊急指針字段有效
- ACK:確認序號字段有效
- PSH:接收方需盡快把該報文段交給應用層
- RST:重置連接
- SYN:同步序號,用於發起一個連接
- FIN:發送端完成發送任務
- 握手連接:
- 第一次握手:客戶 → 服務器(ACK = 0 ,SYN = 1)
- 第二次握手:服務器 → 客戶(ACK = 1 ,SYN = 1)
- 第三次握手:客戶 → 服務器(ACK = 1 ,SYN = 0)
- 握手斷開:
- 第一次握手:客戶 → 服務器(ACK = 1 ,FIN = 1)
- 第二次握手:服務器 → 客戶(ACK = 1 ,FIN = 0)
- 第三次握手:服務器 → 客戶(ACK = 1 ,FIN = 1)
- 第四次握手:客戶 → 服務器(ACK = 1 ,FIN = 0)
注:有時候斷開連接時,只抓得到三個包,是因為第二次、第三次握手放在同一個包里了,合並成一次握手了。
連接建立: TCP協議通過三個報文段完成連接的建立,這個過程稱為三次握手(three-way handshake),過程如下圖所示。

連接終止: 建立一個連接需要三次握手,而終止一個連接要經過四次握手,這是由TCP的半關閉(half-close)造成的。具體過程如下圖所示。

二、wireshark 抓 C# 程序的 TCP 包
這里我事先編寫了一個連接學校服務器的游戲客戶端,可以直接連接上學校的游戲服務器,相關代碼請參考博客:C#編寫網游客戶端連接游戲服務器,下載安裝 wireshark 請參考博客:C#使用TCP/UDP協議通信並用Wireshark抓包分析數據
- 首先運行游戲客戶端(先不要點擊 “ 進入游戲 ”)。

- 此時,打開 wireshark 軟件,由於我現在連接的是學校 wifi ,所以選擇 WLAN 。

- 雙擊打開之后,就可以看到 wireshark 在不停的抓包了。

- 然后點擊游戲客戶端的 “ 進入游戲 ” 按鈕。

- 就成功連接上了學校的游戲服務器端。
- 連接完畢后,點擊 wireshark 左上角的紅色按鈕結束抓包,至此,抓包結束,接下來找一下 TCP 連接時三次握手的包。
- 首先篩選一下(我只需要找 TCP 協議的)。

三次握手連接:

- 第一次握手:客戶端 → 服務器(SYN = 1)。

- 第二次握手:服務器 → 客戶端(ACK =1 ,SYN = 1)。

- 第三次握手:客戶端 → 服務器(ACK = 1 ,SYN = 0)。

以上就是抓到的 TCP 三次握手連接的包,接下來抓一下四次握手斷開的包。
- 點擊魚鰭按鈕,再點擊 Continue without Saving ,重新開始抓包。

- 此時,wireshark 處於抓包狀態,這時我們點擊網游客戶端的 “ 退出游戲 ” 按鈕。

- 然后點擊 wireshark 左上角的紅色按鈕停止抓包,然后我們開始尋找一下四次握手斷開的包。
- 同樣篩選一下 TCP 包,然后找一下四次握手的 TCP 包。
四次握手斷開:
說明:這里第一次握手,里面有個數據 ACK ,這是給游戲服務器確認消息(確定收到了游戲服務器發給我的上一條數據)。

- 第一次握手:客戶端 → 服務端(FIN = 1)。

- 第二次握手:服務端 → 客戶端(ACK = 1)。

- 第三次握手:服務端 → 客戶端(ACK = 1 ,FIN = 1)。

- 第四次握手:客戶端 → 服務端(ACK = 1)。

至此,成功抓到了 TCP 協議三次握手連接、四次握手斷開的包,至於為什么 TCP 協議的連接這么繁瑣呢,主要是為了確保傳輸數據的可靠性。
三、Fiddler 抓 HTTPS 網站包
1)HTTP 協議簡介
TCP 協議是 HTTP 協議的基石——HTTP 協議需要依靠 TCP 協議來傳輸數據。在網絡分層模型中,TCP 被稱為 “傳輸層協議”,而 HTTP 被稱為 “應用層協議”。
HTTP 對 TCP 連接的使用,分為兩種方式:俗稱 “短連接” 和“長連接”(“長連接”又稱 “持久連接”,洋文叫做“Keep-Alive” 或“Persistent Connection”) 假設有一個網頁,里面包含好多圖片,還包含好多外部的CSS 文件和 JS 文件。在 “短連接” 的模式下,瀏覽器會先發起一個 TCP 連接,拿到該網頁的 HTML 源代碼(拿到 HTML 之后,這個 TCP 連接就關閉了)。然后,瀏覽器開始分析這個網頁的源碼,知道這個頁面包含很多外部資源(圖片、CSS、JS)。
然后針對每一個外部資源,再分別發起一個個 TCP 連接,把這些文件獲取到本地(同樣的,每抓取一個外部資源后,相應的 TCP 就斷開) 相反,如果是 “長連接” 的方式,瀏覽器也會先發起一個 TCP 連接去抓取頁面。但是抓取頁面之后,該 TCP 連接並不會立即關閉,而是暫時先保持着(所謂的“Keep-Alive”)。然后瀏覽器分析 HTML 源碼之后,發現有很多外部資源,就用剛才那個 TCP 連接去抓取此頁面的外部資源。
2)使用 Fiddler 抓包
Fiddler 下載官網地址:https://www.telerik.com/download/fiddler
- 填入基本信息后,然后點擊 “ Download for Windows ” 開始下載。

- 下載完成后,點擊安裝程序。

- 點擊 “ I Agree ” 。

- 選擇安裝路徑,然后點擊 “ Install ”。

- 安裝完成后,打開 fiddler 軟件。

- 彈出的窗口點擊 “ No ” 即可,不用理會。
- 下面開始配置 fiddler 。
- 點擊 Tools → Options…

- HTTPS 下,勾選 Decrypt HTTPS traffic ,

- 然后獲取證書,Actions → Trust Root Certificate 。

- 彈窗出來后,一直點擊是就行了。
- 下圖就是 Fiddler 抓取的內容以及 HTTPS 協議執行的過程。

- 下面開始抓取 HTTPS 包分析。
- 首先點擊 Edit -> remove -> all sessions 即可清除所有記錄。

- 打開了 fiddler 軟件,使用瀏覽器訪問百度:www.baidu.com

- 然后再看看 fiddler 軟件,左側的記錄就是抓到的包。

- 開始分析包。
- 下圖中紅色方框內,都是谷歌瀏覽器在向百度服務器發送請求。

- 下圖中是百度服務器返回給谷歌瀏覽器的圖片、JS、CSS、文本文件等等。

- 選擇一個文件,我選的這個文件是圖片文件,可以使用 ImagView 查看。


- Header 標簽——用於顯示 HTTP 請求和響應的頭信息。
- TextView 標簽——用於查看 HTML/JS/CSS 等格式的數據。
- ImageView 標簽——用於顯示圖片格式的數據。
- WebForms 標簽——用於顯示請求的表單數據。如登錄請求,就可以通過它查查看登錄用戶名密碼信息。它以表格形式顯示。
- Raw 標簽——可以查看原始的符合 HTTP 標准的請求和響應頭。
- Auth 標簽——可以查看授權 Proxy-Authorization 和 Authorization 的相關信息。
- Cookies 標簽——可以看到請求的 cookie 和響應的 set-cookie 頭信息。
- XML 和 JSON 標簽——用於顯示 XML 和 JSON 格式的數據。
這里可以看到采用的連接方式保持的是長連接。

更多的 Fiddler 使用方法請參考博客:Fiddler抓包1_介紹及界面概述
四、總結
雖然沒有使用 Fiddler 抓到 HTTPS 網站的 TCP 三次握手連接,這是由於 Fiddler 只能抓取 HTTP 協議,而 HTTP 協議是 TCP 的一個分支,當使用瀏覽器訪問一個服務器的時候,首先都是通過 TCP 三次握手連接,然后才使用 HTTP 協議進行數據的交互。
