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