摘要:
本文簡單介紹了TCP面向連接理論知識,詳細講述了TCP報文各個字段含義,并從Wireshark俘獲
分組中選取TCP連接建立相關報文段進行分析。
一、概述
TCP是面向連接的可靠傳輸協議,兩個進程互發數據之前需要建立連接,這里的連接只不過是端系
統中分配的一些緩存和狀態變量,中間的分組交換機不維護任何連接狀態信息。連接建立整個過程
如下(即三次握手協議):
首先,客戶機發送一個特殊的TCP報文段;
其次,服務器用另一個特殊的TCP報文段來響應;
最后,客戶機再用第三個特殊報文段作為響應。
20130115105432114.png (46.76 KB, 下載次數: 85)
下載附件
2017-5-7 01:56 上傳
圖1 三次握手協議示意圖[1]
二、TCP報文格式
2.1 概述
為了提供可靠的數據傳輸,TCP報文首部字段有較多的字段,TCP報文格式如下圖:
20130115105433483.png (30.36 KB, 下載次數: 91)
下載附件
2017-5-7 01:56 上傳
圖2 TCP報文格式
源和目標端口
用于多路復用/多路分解來自或送至上層應用的數據,可以這樣理解,端口用來標識
同一臺計算機的不同進程。
序列號和確認號
這兩個字段是TCP可靠傳輸服務的關鍵部分,序列號是該報文段首字節的字節流編號
(TCP把數據看成是有序的字節流,TCP隱式地對數據流的每個字節進行編號)。這樣理
解可能更直觀,當報文被分解成多個報文段時,序列號就是報文段首字節在整個報文的
偏移量。確定號指定下一個期待的字節。TCP是全雙工的,假設從主機A接收到主機B
的數據,則主機A填充進報文段的確認號是主機A期望從主機B收到的下一個字節序號。
還沒理清這兩者的關系?見下圖(三次握手):
20130115105433424.png (22.69 KB, 下載次數: 104)
下載附件
2017-5-7 01:56 上傳
圖3 正常情況下TCP連接建立過程
首部長度(4位)
因為選項是不定長的,這就需要標識整個首部字段的長度(單位是32位字),即5+選項
個數。4位,單位是32位字,所以首部最長是15*4=60字節,即選項最長是40字
節(10個選項)。
標志
URG
指示報文段里存在著被發送方的上層實體標記為"緊急"數據,當URG=1時,其后的緊
急指針指示緊急數據在當前數據段中的位置(相對于當前序列號的字節偏移量),TCP接
收方必須通知上層實體。
ACK
當ACK=0時,表示該數據段不包含確認信息,當ACK=1時,表示該報文段包括一個對
已被成功接收報文段的確認。
PSH
當PSH=1時,接收方在收到數據后立即將數據交給上層,而不是直到整個緩沖區滿。
RST
用于重置一個已經混亂的連接(如主崩潰),也可用于拒絕一個無效的數據段或者拒絕
一個連接請求。一般而言,如果你得到的數據段被設置了RST位,那說明你這一
端有問題了。
SYN
用于建立連接過程,在連接請求中,SYN=1和ACK=0表示該數據段沒有使用捎帶
的確認域,而連接應答捎帶一個確認,即SYN=1和ACK=1。
注:捎帶是指對客戶機到服務器數據的確認被裝載在一個承載服務器到客戶機的數
據報文段中。
FIN
用于釋放一個連接,表示發送方已經沒有數據要傳輸了。此時,接收方可能繼續接
收數據,好在SYN和FIN數據段都有序列號,從而保證了這兩種數據段以正確
順序被處理。
窗口大小
用于流控制(確保連接的任何一方都不會過快地發送過量的分組而淹沒另一方),窗口
大小指定了從被確認的字節算起可以發送多少個字節。
校驗和
提供了額外可靠性,在計算檢驗和的時候,TCP的Checksum域設為0,如果數據域
的字節數為奇數,則數據域填補一個額外的0字節。校驗和算法:將所有的16位字按
1的補碼形式累加起來,取累加結果的補碼。因此,當接收方執行同樣計算時(包括
Checksum域),結果應該是0。
緊急指針
參考標志字段的URG位。
選項
選項部分是為了適合復雜網絡環境和更好地服務于應用層設計的。TCP選項最長
是40字節。詳情見2.2。
數據
無任何數據的TCP段也是合法的,通常用于確認和控制信息。
2.2 選項字段[2]
TCP選項部分很好出現在已經建立連接的會話中,只要出現在TCP連接建立階段,
即三次握手。TCP選項部分實際運用有以下幾種:
(1)最大報文傳輸段(MMS, Maximum Segment Size)
用于發送發與接收方協商最大報文段長度(僅僅是凈荷數據,不包括TCP首部字段)。
TCP在三次握手中,每一方都會通告期望收到的MSS(MSS只出現在SYN數據包中),
如果一方不接受另一方的MSS值,則使用默認的536字節凈荷數據,即主機能夠接
受20+536字節的TCP報文段。
(2)窗口擴大選項(Window scaling)
TCP報文的窗口大小字段占16位,即最大值是65535,但隨著時延和帶寬比較大的
通信產生(如衛星通信),需要更大的窗口滿足性能和吞吐率,這就是窗口擴大選項
存在的意義。例子見參考資料[2]。
Windows scaling占3個字節,最后一個字節是移位值(Shift count),即首部的窗口
位數16向左移動,如移位值為14,則新的窗口最大值增大到65535*(2^14)。
窗口擴大選項是在TCP建立之初進行協商,如果已實現了窗口擴大,當不再需要
擴大窗口時,發送移位值=0就可以恢復到原窗口大小,即65535。
(3)選擇確認選項(SACK, Selective Acknowledgements)
考慮這樣情況,主機A發送報文段12345,主機B收到135且報文無差錯,SACK用來
確保只重傳缺少的報文段,而不是重傳所有報文段。
SACK選項需要2個功能字節,一個用來指明使用SACK選項(SACK Permission),
另一指明這個選項占多少字節。
那怎么形容丟失的報文段2,說明2的左右邊界分別是1、3。TCP的數據報文是有
字塊邊界的,而這種邊界是由序列號表示的。
最多能指明多少個字節塊的邊界信息呢?答案是4個。這是因為選項字段最大是40
字節,去除2個功能字節,序列號是32位即4字節,并且需要左右邊界,所以
(40-2)/8 = 4。
(4)時間戳選項(timestamps)
時間戳選項用來計算往返時間RTT,發送方在發送報文段時把當前時鐘的時間值
放入時間戳字段,接收方將該時間戳字段的值復制到確認報文中,當接收方收到
確認報文,對比確認報文的時間戳(等于發送方發送報文段的時間戳)和現在的時鐘,
即可算出RTT。
時間戳選項還可用于防止回繞序號PAWS。序列號只有32位,每2^32個序列號就會
回繞(想想環形隊列),采用時間戳選項很容易區分相同序列號的報文段。
(5)NOP(NO-Operation)
TCP的頭部必須是4字節的倍數,而大多數選項不是4字節倍數,不足的用NOP填充。
除此之外,NOP也用于分割不同的選項數據,如窗口擴大選項和SACK之間使用NOP
隔離(下面的實例將看到這一點)。
三、實例解析
3.1 概述
還是以訪問百度首頁為例,首先用DNS協議將URL解析成IP地址,接著在客戶機和服務
器間建立TCP連接,用Wireshark俘獲的分組如下圖:
20130115105434198.png (13.88 KB, 下載次數: 101)
下載附件
2017-5-7 01:56 上傳
圖4 Wireshark俘獲建立TCP連接分組
你一看會覺得有些奇怪,理論上應該是3個分組的,怎么有6個分組?先不急,先把這6個
報文收發示意圖作出來(結合時間和報文含義),如下:
20130115105434604.png (27.95 KB, 下載次數: 97)
下載附件
2017-5-7 01:56 上傳
圖5 TCP連接建立實例
從圖可知,連接建立伊始,客戶機發了兩個報文段,這也許是為了更快建立連接(假設有
個請求報文段丟失,也不至于要等一段時間,重發報文)。接下來,以19、21、22(上圖
紅色線條所示)分析TCP連接建立過程。
3.1 第一次握手19
Wireshark俘獲TCP連接第一次握手的報文段如下:
20130115105434612.png (29.26 KB, 下載次數: 89)
下載附件
2017-5-7 01:56 上傳
圖6 TCP連接第一次握手實例
這里主要挑幾個字段分析:
標志字段,SYN=1、ACK=0表示該數據段沒有使用捎帶的確認域。
最大報文段長度(MMS)1460是怎么來的,鏈路層的以太網物理特性決定數據幀長度為
1500(即MTU,最大傳輸單元),1460=1500-20(IP首部長度)-20(TCP首部長度)。不要被
該報文首部長度32字節所迷惑,這只是建立連接過程。MSS與MTU關系見下圖[2]:
20130115105435635.png (60.21 KB, 下載次數: 102)
下載附件
2017-5-7 01:56 上傳
圖7 MSS與MTU關系
NOP字段,可以作為不足4倍數字節填充,也可作為選項間分隔,該報文段出現了3個
NOP,具體功能見下圖:
20130115105435492.png (16.38 KB, 下載次數: 79)
下載附件
2017-5-7 01:56 上傳
圖8 TCP報文NOP字段
3.3 第二次握手21
服務器響應客戶端TCP報文段,此時確認號為1了,SYN=1、ACK=1表明連接應答捎
帶一個確認,Wireshark俘獲分組如下:
20130115105435496.png (31.31 KB, 下載次數: 77)
下載附件
2017-5-7 01:56 上傳
圖9 TCP連接第二次握手實例
為什么MSS是1452而不是1460?這是因為使用PPPoE(Point-to-Point over Ethernet,
可以使以太網的主機通過一個簡單的橋接設備連到一個無端的接入集中器上[3])撥號上網,
PPoP首部是8個字節,所以PPPoE的MTU是1492,MSS也就為1492-40=1452。
那么,TCP連接建立后數據傳輸的MSS是多少呢,1460 or 1452 or 536 ?我的理解是
默認值536,這樣理解對嗎?求指點!
3.4 第三次握手22
客戶機再次服務器的報文段,此時序列號和確認號都為1,沒有選項字段,Wireshark
俘獲的分組信息如下:
20130115105436552.png (24.85 KB, 下載次數: 110)
下載附件
2017-5-7 01:56 上傳
圖10 TCP連接第三次握手實例
值得注意的,因為窗口擴展大小協商未果,所以就不擴大窗口了,即窗口大小最大
為65535。
如此,TCP連接建立:-)
|