TCP 協議
TCP 協議給使用者提供了兩種服務,分別是面向連接的服務和可靠的數據傳輸服務,我們簡單介紹一下。簡單來說面向連接的含義是客戶機和服務器之間需要建立連接,在位於應用層的數據開始交互之前,TCP 協議首先要先讓客戶機和服務器進行一次握手。這么做相當於告知彼此接下來需要進行數據的交互,請雙方做好准備,具體的實現方式為雙方在傳輸層交互信息。握手階段結束之后,就能夠建立起 TCP 連接,雙方應用程序的數據交互完畢之后,還需要切斷這個連接。
所謂 TCP 連接是一種邏輯上的連接,它可以提供全雙工服務,即應用層數據可以在建立連接的進程之間相互傳輸。TCP 連接也是點對點的,因為這是針對單個發送方和單個接收方之間的連接。
接下來再看看何謂可靠的數據傳輸服務,即雙方的數據交互在 TCP 協議的保障下,彼此發出的數據能夠無差別、按照正確順序傳遞給對方。即 TCP 會將發送方通過套接字傳出的字節流,在保證字節不發生丟失和出現多余的情況下,將字節流交付給接收方的套接字。

TCP 報文段結構

字段解析
源端口、目的端口:各占 2 字節,端口是運輸層與應用層的服務接口,運輸層的復用和分用功能都要通過端口才能實現。
序號:占 4 字節,TCP 連接中傳送的數據流中的每一個字節都編上一個序號,序號字段的值則指的是本報文段所發送的數據的第一個字節的序號。
確認號:占 4 字節,是期望收到對方的下一個報文段的數據的第一個字節的序號。
首部長度:占 4 位,它指出 TCP 報文段的數據起始處距離 TCP 報文段的起始處有多遠,的單位是 32 位字(以 4 字節為計算單位)。
保留:占 6 位,保留為今后使用,但目前應置為 0。
接收窗口:占 2 字節,用於流量控制,指示接收方願意接收的字節數量,單位為字節。
檢驗和:占 2 字節。檢驗和字段檢驗的范圍包括首部和數據這兩部分。在計算檢驗和時,要在 TCP 報文段的前面加上 12 字節的偽首部。
選項:長度可變。TCP 最初只規定了最大報文段長度 MSS,表示緩存所能接收的報文段的數據字段的最大長度是 MSS 個字節。
標志字段
緊急 URG:當 URG = 1 時,表明緊急指針字段有效。它告訴系統此報文段中有緊急數據,應盡快傳送(相當於高優先級的數據)。
確認 ACK:只有當 ACK = 1 時確認號字段有效,當 ACK = 0 時確認號無效。
推送 PSH(PuSH):接收 TCP 收到 PSH = 1 的報文段,就盡快地交付接收應用進程,不再等到整個緩存都填滿了后再向上交付。
復位 RST(ReSeT):當 RST = 1 時,表明 TCP 連接中出現嚴重差錯(如由於主機崩潰或其他原因)必須釋放連接,然后再重新建立運輸連接。
同步 SYN:同步 SYN = 1 表示這是一個連接請求或連接接受報文。
終止 FIN(FINish):用來釋放一個連接。FIN = 1 表明此報文段的發送端的數據已發送完畢,並要求釋放運輸連接。
捕獲從計算機到遠程服務器的批量 TCP 傳輸
首先使用 Wireshark 來獲取文件從計算機到遠程服務器的 TCP 傳輸的數據包內容。通過訪問一個網頁,在網頁上輸入您計算機上儲存的文件名稱,然后使用 HTTP POST 方法將文件傳輸到 Web 服務器,並在此期間運行 Wireshark 以獲取從計算機發送和接收的 TCP 區段的內容。執行如下操作:
- 在電腦上保存一個 ASCII 檔案文件:


2. 打開 http://gaia.cs.umass.edu/wireshark-labs/TCP-wireshark-file1.html :

3. 使用此表單中的“選擇文件”按鈕上傳文件:

4. 啟動 Wireshark 並開始數據包捕獲:

5. 返回瀏覽器,按 “Upload alice.txt file” 按鈕將文件上傳到 gaia.cs.umass.edu 服務器:

6.停止 Wireshark 數據包捕獲:
干擾巨大,我還是用現成的包來分析吧。

跟蹤包的初步觀察
在過濾器指定窗口中輸入 “tcp” 過濾 Wireshark 視窗中顯示的數據包:

可以應該看到的是計算機和 gaia.cs.umass.edu 之間的一系列 TCP 和 HTTP 訊息,首先是看到包含 SYN 訊息的初始三次握手。

接下來有 HTTP POST 訊息。

在 Wireshark 顯示的 Info 列中有不少“[重新組裝的 PDU 的 TCP 段]”,以指示此 TCP 區段包含屬於上層協議訊息的數據(這里是 HTTP)。

還有 gaia.cs.umass.edu 返回到您的計算機的 TCP ACK 區段。

回答以下問題:
- 將文件傳輸到 gaia.cs.umass.edu 的客戶端計算機(源)使用的 IP 地址和 TCP 端口號是什么?

IP 地址:192.168.1.102
TCP 端口號:1161
2. gaia.cs.umass.edu 的 IP 地址是什么? 在哪個端口號上發送和接收此連接的 TCP 區段?

IP 地址:128.119.245.12
接收連接的端口號:80
現在我們關注 TCP 而不是 HTTP,因此更改 Wireshark 的“捕獲數據包列表”視窗,以便顯示有關包含 HTTP 訊息的 TCP 區段的信息。要讓 Wireshark 執行此操作,選擇 Analyze-> Enabled Protocols。

然后取消勾選 HTTP 框,並選擇確定。

這些是計算機和 gaia.cs.umass.edu 之間發送的一系列 TCP 區段。
TCP Basics
回答下列問題:
- 用於在客戶端計算機和 gaia.cs.umass.edu 之間啟動 TCP 連接的 TCP SYN 區段的序列號是什么?將區段標識為 SYN 區段的區段有什么功能?

序列號為 0,功能是開始三次握手,主機發送 SYN 請求服務器建立連接,這是三次握手的第一步。
2. gaia.cs.umass.edu 發送給客戶端計算機以回復 SYN 的 SYNACK 區段的序列號是多少?

序列號為 0。
SYNACK 區段中的 Acknowledgment 欄位的值是多少?


Acknowledgment 欄位的值是 1。
Gaia.cs.umass.edu 是如何確定此 Acknowledgment 的數值的?在將區段標識為 SYNACK 區段的區段在連線中有什么功能?
Ack 字段用於表示確認字段中的值是有效的,功能是說明服務器成功接收了我們發出的連接請求,並發送 SYN-ACK 確認報文。
3. 包含 HTTP POST 命令的 TCP 區段的序列號是多少?

序列號為 1,其中 PSH 表示有數據傳輸。
4. 將包含 HTTP POST 的 TCP 區段視為 TCP 連接中的第一個區段。前六個 TCP 區段的長度是多少?在這個 TCP 連線中前 6 個 TCP 區段的序列號是什么(包括包含 HTTP POST 的段)?每區段發送的時間是什么時候?收到的每個區段的 ACK 是什么時候?鑒於發送每個 TCP 區段的時間與收到確認的時間之間的差異,六個區段中每個區段的 RTT 值是多少?收到每個 ACK 后,EstimatedRTT 值是什么?假設第一個 EstimatedRTT 的值等於第一個區段的測量 RTT。
- EstimatedRTT 運算公式
EstimatedRTT = (1 - a) × EstimatedRTT + a × SampleRTT
其中 a 使用推薦值 0.125。
區段一:

長度:565
序列號:1
發送時間:2004 年 8 月 21 日 21:44:20.596858000

RTT:0.027460000 seconds
EstimatedRTT = RTT = 0.027460000 seconds
區段二:

長度:1460
序列號:566
發送時間:2004 年 8 月 21 日 21:44:20.612118000

RTT:0.035557000 seconds
EstimatedRTT = 0.875 × 0.027460000 + 0.125 × 0.035557000 = 0.028472125 seconds
區段三:

長度:1460
序列號:2026
發送時間:2004 年 8 月 21 日 21:44:20.624407000

RTT:0.070059000 seconds
EstimatedRTT = 0.875 × 0.028472125 + 0.125 × 0.070059000 = 0.033670484 seconds
區段四:

長度:1460
序列號:3486
發送時間:2004 年 8 月 21 日 21:44:20.625071000

RTT:0.114428000 seconds
EstimatedRTT = 0.875 × 0.033670484 + 0.125 × 0.114428000 = 0.043765173 seconds
區段五:

長度:1460
序列號:4946
發送時間:2004 年 8 月 21 日 21:44:20.647786000

RTT:0.139894000 seconds
EstimatedRTT = 0.875 × 0.043765173 + 0.125 × 0.139894000 = 0.055781277 seconds
區段六:

長度:1460
序列號:6406
發送時間:2004 年 8 月 21 日 21:44:20.648538000

RTT:0.189645000 seconds
EstimatedRTT = 0.875 × 0.055781277 + 0.125 × 0.189645000 = 0.072514242 seconds

5. 對於整個跟蹤包,收到的最小可用緩沖區空間量是多少?缺少接收器緩沖區空間是否會限制發送方傳送 TCP 區段?

對於服務器而言,收到的最小可用緩沖區空間量為 6780。

對於主機而言,收到的最小可用緩沖區空間量為 5840。
缺少接收器緩沖區空間會限制發送方傳送 TCP 區段,這是因為 TCP 的流量控制服務,能夠消除發送方使接收方緩存溢出的可能性,使得發送方的發送速率與接收方應用程序的讀取速率相匹配。實現的方式是滑動窗口協議,具體可參考后文附帶的資料。
6. 在跟蹤文件中是否有重傳的區段?
檢查數據包的時間序列:

因為序列號呈增大趨勢,因此沒有重傳。
7. 接收器通常在 ACK 中確認多少數據?是否可以識別接收方每隔一個接收到的區段才發送確認的情況?
(這個回答難以保證正確,歡迎糾錯)接收器通常在 ACK 中確認序列號,可以確認,根據 ACK 序列號的順序來推測。
8. TCP 連接的吞吐量(每單位時間傳輸的⫿節數)是多少?如何計算這個值?
平均吞吐量 = 傳輸數據的比特數 F ÷ 接收方接收所有數據所用時間 T
首先看看傳輸數據的比特數 F = 164090 bytes

再看看接收方接收所有數據所用時間 T = 5.297341000 seconds

吞吐量 = 164090 ÷ 5.297341000 = 30.975917918064 Kb/s
TCP 擁塞控制
現在檢查從客戶端服務器的每單位時間發送的數據量,從 Wireshark 窗口中的原始數據計算這些數值。

- 每個點代表一個發送的 TCP 區段,繪制區段的序列號與發送的時間,堆疊在一起的一組點表示發送方背靠背發送的一系列數據包。使用時序圖(Stevens)查看從客戶端發送到 gaia.cs.umass.edu 服務器的區段的序列號與時間關系圖。您能否確定 TCP 的慢啟動階段的開始和結束位置,以及擁塞避免接管的位置?
慢啟動的原理是:連接開始時,發送速率呈指數型增長。因此 TCP 開始發送的速率很慢,但是慢啟動階段增長很快。

如圖所示,慢啟動階段的開始肯定是在第一個 TCP 區段發出去的時候,也就是分組 5 發送的時候。

結束位置是什么時候?觀察到這樣的指數型增長的速率在分組 23 處卡殼了,說明這個時候發生了擁塞,進入擁塞避免階段。

這個區域就是擁塞避免區段。

2. 評論測量數據與我們在文本中研究的 TCP 的理想化行為的不同之處。
慢啟動是 TCP 在擁塞控制方面做的努力之一,但是對於一些數據量較小的小文件,在網絡暢通的情況下發送非常快,甚至可能在慢啟動結束之前就已經發送完畢。這個問題要怎么理解呢?例如我需要發送一個 5 單位大小的文件,假定一個窗口在一個單位時間內可以發送一個單位大小的數據報。如果是初始窗口為 1 個的慢啟動,窗口按照指數型增長,就需要 3 個單位時間才能發送完畢。而如果一開始就擁有大於 5 個的窗口,則 1 個單位時間就可以發送完畢,這個時候慢啟動反而來制約了文件的快速發送,從而影響了效率。
由此可見慢啟動並不是永遠都是高效的,在一些情況下效率不會達到最好。這種情況不可否認,不過慢啟動在擁塞控制方面的貢獻,在總體上仍然是一個很好的手法!
參考資料
《計算機網絡 自頂向下方法》 [美] James F.Kurose,Keith W.Ross 著,陳鳴 譯,機械工業出版社
TCP
滑動窗口協議
一篇帶你讀懂TCP之“滑動窗口”協議
