與UDP不同的是,TCP提供了一種面向連接的、可靠的字節流服務。TCP協議的可靠性主要有以下幾點保障:
(1)應用數據分割成TCP認為最適合發送的數據塊。這部分是通過“MSS”(最大數據包長度)選項來控制的,通常這種機制也被稱為一種協商機制,MSS規定了TCP傳往另一端的最大數據塊的長度。值得注意的是,MSS只能出現在SYN報文段中,若一方不接收來自另一方的MSS值,則MSS就定為536字節。一般來講,在不出現分段的情況下,MSS值還是越大越好,這樣可以提高網絡的利用率。
(2)重傳機制。設置定時器,等待確認包。
(3)對首部和數據進行校驗。
(4)TCP對收到的數據進行排序,然后交給應用層。
(5)TCP的接收端丟棄重復的數據。
(6)TCP還提供流量控制。(通過每一端聲明的窗口大小來提供的)
1.TCP/IP 協議數據封裝的過程
以傳輸層采用TCP或者UPD、網絡層采用IP、鏈路層采用Ethernet為例,可以看到TCP/IP中報文的封裝過程如圖所示。用戶數據經過應用層協議封裝后傳遞給傳輸層,傳輸層封裝TCP頭部,交給網絡層,網絡層封裝IP頭部后,再交給數據鏈路層,數據鏈路層封裝Ethernet幀頭和幀尾,交給物理層,物理層以比特流的形式將數據發送到物理線路上。
不同的協議層對數據包有不同的稱謂,在傳輸層叫做段(segment),在網絡層叫做數據報(datagram),在鏈路層叫做幀(frame)。數據封裝成幀后發到傳輸介質上,到達目的主機后每層協議再剝掉相應的首部,最后將應用層數據交給應用程序處理。
目的主機收到數據包后,如何經過各層協議棧最后到達應用程序呢?整個過程如下圖所示。
以太網驅動程序(網卡)首先根據以太網首部中的“上層協議”字段確定該數據幀的有效載荷(payload,指除去協議首部之外實際傳輸的數據)是IP、ARP還是RARP協議的數據報,然后交給相應的協議處理。假如是IP數據報,IP協議再根據IP首部中的“上層協議”字段確定該數據報的有效載荷是TCP、UDP、ICMP還是IGMP,然后交給相應的協議處理。假如是TCP段或UDP段,TCP或UDP協議再根據TCP首部或UDP首部的“端口號”字段確定應該將應用層數據交給哪個用戶進程。IP地址是標識網絡中不同主機的地址,而端口號就是同一台主機上標識不同進程的地址,IP地址和端口號合起來標識網絡中唯一的進程。
注意,雖然IP、ARP和RARP數據報都需要以太網驅動程序來封裝成幀,但是從功能上划分,ARP和RARP屬於鏈路層,IP屬於網絡層。雖然ICMP、IGMP、TCP、UDP的數據都需要IP協議來封裝成數據報,但是從功能上划分,ICMP、IGMP與IP同屬於網絡層,TCP和UDP屬於傳輸層。
2.TCP/IP 數據包
我們通過 Wireshark 抓包:就分別看到五層數據:
第一行Frame 3339:物理層數據幀:線路83字節,實際捕獲83字節
第二行Ethernet II:鏈路層網卡,以太網協議版本II,源地址:廠名_序號(網卡地址),目的:廠名_序號(網卡地址)
第三行Internet Protocol Version 4:網絡層ip數據包,IPV4,源IP地址:10.44.13.7;目的IP是:10.171.8.154
第四行Transmission Control Protocol:傳輸層TCP數據包:源端口21000,目的端口:52529;Seq序列號:每發送一個RTP數據包,序列 號就加1;ACK是TCP數據包首部中的確認標志,對已接收到的TCP報文進行確認,其為 183589表示確認號有效;Len長度是17字節;
第五行data:數據
整個數據封裝的格式如下圖所示:
Wireshark顯示的下面這些數據信息的順序與各數據包內各字段的順序相同,其他幀的內容展開與此類似。
幀號 時間 源地址 目的地址 高層協議 包內信息概況
No. Time Source Destination Protocol Info
1 0.000000 202.203.44.225 202.203.208.32 TCP 2764 > http [SYN] Seq=0 Len=0 MSS=1460 源端口>目的端口[請求建立TCP鏈接]
第一層物理層的數據幀概況
Frame 1 (62 bytes on wire, 62 bytes captured) 1號幀,線路62字節,實際捕獲62字節
Arrival Time: Jan 21, 2008 15:17:33.910261000 捕獲日期和時間
[Time delta from previous packet:0.00000 seconds]此包與前一包的時間間隔
[Time since reference or first frame: 0.00 seconds]此包與第1幀的間隔時間
Frame Number: 1 幀序號
Packet Length: 62 bytes 幀長度
Capture Length: 62 bytes 捕獲長度
[Frame is marked: False] 此幀是否做了標記:否
[Protocols in frame: eth:ip:tcp] 幀內封裝的協議層次結構
[Coloring Rule Name: HTTP] 用不同顏色染色標記的協議名稱:HTTP
[Coloring Rule String: http || tcp.port == 80] 染色顯示規則的字符串:
第二層數據鏈路層以太網幀頭部信息
Ethernet II, Src: AcerTech_5b:d4:61 (00:00:e2:5b:d4:61), Dst: Jetcell_e5:1d:0a (00:d0:2b:e5:1d:0a)
以太網協議版本II,源地址:廠名_序號(網卡地址),目的:廠名_序號(網卡地址)
Destination: Jetcell_e5:1d:0a (00:d0:2b:e5:1d:0a) 目的:廠名_序號(網卡地址)
Source: AcerTech_5b:d4:61 (00:00:e2:5b:d4:61) 源:廠名_序號(網卡地址)
Type: IP (0x0800) 幀內封裝的上層協議類型為IP(十六進制碼0800)看教材70頁圖3.2
第三層網層IP包頭部信息
Internet Protocol, Src: 202.203.44.225 (202.203.44.225), Dst: 202.203.208.32 (202.203.208.32) 互聯網協議,源IP地址,目的IP地址
Version: 4 互聯網協議IPv4(此部分參看教材119頁圖4.15的IPv4數據報字段結構)
Header length: 20 bytes IP包頭部長度
Differentiated Services Field:0x00(DSCP 0x00:Default;ECN:0x00)差分服務字段
Total Length: 48 IP包的總長度
Identification:0x8360 (33632) 標志字段
Flags: 標記字段(在路由傳輸時,是否允許將此IP包分段,教材125頁)
Fragment offset: 0 分段偏移量(將一個IP包分段后傳輸時,本段的標識)
Time to live: 128 生存期TTL
Protocol: TCP (0x06) 此包內封裝的上層協議為TCP
Header checksum: 0xe4ce [correct] 頭部數據的校驗和
Source: 202.203.44.225 (202.203.44.225) 源IP地址
Destination: 202.203.208.32 (202.203.208.32) 目的IP地址
以下為傳輸層TCP數據段頭部信息
Transmission Control Protocol, Src Port: 2764 (2764), Dst Port: http (80), Seq: 0, Len: 0 傳輸控制協議TCP的內容
Source port: 2764 (2764)源端口名稱(端口號)(此部分參看教材149頁圖5.7)
Destination port: http (80) 目的端口名http(端口號80)
Sequence number: 0 (relative sequence number) 序列號(相對序列號)
Header length: 28 bytes 頭部長度
Flags: 0x02 (SYN) TCP標記字段(本字段是SYN,是請求建立TCP連接)
Window size: 65535 流量控制的窗口大小
Checksum: 0xf73b [correct] TCP數據段的校驗和
Options: (8 bytes) 可選項
3.TCP 數據包的報文
1、TCP建立連接,斷開,數據傳輸都是使用同樣數據報文格式。
其中我們抓包看到Transmission Control Protocol 首部的數據信息:
Transmission Control Protocol, Src Port: 21000, Dst Port:52529, Seq: 12936, ACK 183589 Len: 17 傳輸控制協議TCP的內容
Source port: 21000源端口名稱(端口號)(用於尋找發端應用進程)
Destination port: 52529 目的端口
Sequence number: 0 (relative sequence number) 序列號(相對序列號,此序列號用來確定傳送數據的正確位置,且序列號,用來偵測丟失的包);
[Next sequence number: 215 (relative sequence number)] #下一個序列號
Acknowledgement number :183589 是32位確認序號,確認其有效;
Header length: 32 bytes 頭部長度
Flags: 0x02 (SYN) TCP標記字段(本字段是SYN,是請求建立TCP連接)
Window size value: 6364 流量控制的窗口大小
Checksum: 0xf73b [correct] TCP數據段的校驗和
Options: (12 bytes) 可選項
下面說明詳細說明:
源端口和目的端口:各占2個字節,16比特的端口號加上32比特的IP地址,共同構成相當於傳輸層服務訪問點的地址
Seq序號:占4個字節,是本報文段所發送的數據部分第一個字節的序號。在TCP傳送的數據流中,每一個字節都有一個序號。
1、假設某時序號為300,簡單的理解就是發送方告訴接收端“我發送的數據是從第300開始的”。
2、假設起數據len=100字節,則下一個報文段的序號就是400;
ACK 確認序號:占4字節,是期望收到對方下次發送的數據的第一個字節的序號,也就是期望收到的下一個報文段的首部中的序號;
1、確認序號是上一次已經成功接收到數據字節序號加1。還可以理解為接收端告訴發送端下一次想接收開始序號。假設某時確認序號為1000,簡單的理解就是接收方告訴發送方“我已經收到第999序號了,我下一次想接收的數據是從1000開始的”。
2、由於序號字段有32比特長,可以對4GB的數據進行編號,這樣就可保證當序號重復使用時,舊序號的數據早已在網絡中消失了;
在數據傳輸過程中:
第一報文發送:Seq1=1 ACK1=1 len1=359
收到第一個報文回復:Seq2 =1 ACK2=Seq1+ ACK1= 360, len1=17
下一個報文發送:Seq3=ACK2 =Seq1 (上一個發送的報文seq1 +上一個發送的報文len1)=360 ACK3=Seq1+ ACK1 =18 len3=0
兩次ACK一樣:你應該發數據,但我們沒有收到數據,所以你還得同樣ack繼續發送
Header length首部長度(4位):報文頭長度(單位:位)/32
1000(轉化為10進制為8,8*32/8 = 32,該報文報頭長度為32個字節)
存在該字段是因為TCP報頭中任選字段長度可變
報頭不包含任何任選字段則長度為20字節;4位所能表示的最大值為1111,轉化為10進制為15,15*32/8 = 60,故報頭最大長度為60字節
Flag標志位:
Nonce Sum:有效排除潛在的ECN濫用,RFC 3540
Congestion Window Reduced(CWR):擁塞窗口減少標志
ECN-Echo:ECE / ECN標志
URG: 緊急指針有效(urgentpointer) 當URG=1時,表明此報文應盡快傳送,而不要按原來的排隊順序來傳送。與“緊急指針”字段配合使用,緊急指針指出在本報文段中的緊 急數據的最后一個字節的序號,使接收方可以知道緊急數據共有多長;
ACK:確認序號有效,只有當ACK=1時,確認序號字段才有意義;
PSH:當PSH=1時,表明請求遠地TCP將本報文段立即傳送給其應用層,而不要等到整個緩存都填滿了之后再向上交付。
RST:重建連接,當RST=1時,表明出現嚴重差錯,必須釋放連接,然后再重建傳輸連接。復位比特還用來拒絕一個非法的報文段或拒絕打開一個連接;
SYN:同步序號用來發起一個連接,在建立連接時使用,當SYN=1而ACK=0時,表明這是一個連接請求報文段。對方若同意建立連接,在發回的報文段中使SYN=1和ACK=1。因此,SYN=1表示這是一個連接請求或連接接受報文,而ACK的值用來區分是哪一種報文;
FIN: 發端完成發送任務(主動關閉),用來釋放一個連接,當FIN=1時,表明欲發送的字節串已經發完,並要求釋放傳輸連接;
window窗口大小(2字節):(TCP的流量控制由連接的每一端通過聲明的窗口大小來提供。窗口大小為字節數,起始於確認序 號字段指明的值,這個值是接收端正期望接收的字節。窗口大小是一個16bit字段,因而窗口大小最大為65535字節)。
Checksum檢驗和(2字節):檢驗和覆蓋整個TCP報文段;強制字段,由發送端計算存儲,由接收端進行驗證
Urgent pointer 緊急指針(2字節):當Urgent標志置1時,緊急指針才有效
Options選項 :選項字段允許每台主機設定能夠接受的最大TCP載荷能力(缺省536字節) 。
4.TCP數據報文的Options
當前,TCP常用的Option如下所示:
Kind
(Type)
Length
Name
Reference
描述 & 用途
0
1
EOL
RFC 793
選項列表結束
1
1
NOP
RFC 793
無操作(用於補位填充)
2
4
MSS
RFC 793
最大Segment長度
3
3
WSOPT
RFC 1323
窗口擴大系數(Window Scaling Factor)
4
2
SACK-Premitted
RFC 2018
表明支持SACK
5
可變
SACK
RFC 2018
SACK Block(收到亂序數據)
8
10
TSPOT
RFC 1323
Timestamps
19
18
TCP-MD5
RFC 2385
MD5認證
28
4
UTO
RFC 5482
User Timeout(超過一定閑置時間后拆除連接)
29
可變
TCP-AO
RFC 5925
認證(可選用各種算法)
253/254
可變
Experimental
RFC 4727
保留,用於科研實驗
一般Option的格式為TLV結構,如下所示:
Kind / Type(1 Byte)
Length(1 Byte)
Value
1. EOL和NOP Option(Kind 0、Kind 1)只占1 Byte,沒有Length和Value字段;
2. NOP用於 將TCP Header的長度補齊至32bit的倍數(由於Header Length字段以32bit為單位,因此TCP Header的長度一定是32bit的倍數);
3. SACK-Premitted Option占2 Byte,沒有Value字段;
4. 其余Option都以1 Byte的“Kind”開頭,指明Option的類型;Length指明Option的總長度(包括Kind和Length)
5. 對於收到“不能理解”的Option,TCP會無視掉,並不影響該TCP Segment的其它內容;
① .Maximum Segment Size (MSS) Option
一般情況下,通信雙方在建立連接時,SYN Segment中會攜帶MSS Option,MSS指明本端可以接受的最大長度的TCP Segment(Payload,不含TCP Header),也就是說,對端發送數據的長度不應該大於MSS(單位Byte)。
————
1. 首先要明確一點,MSS並非和對端協商的值,而是對對端發送數據長度的“限制”,表明在整個TCP連接期間,都不會接收長度大於MSS的TCP Segment。
2. 如果收到的SYN中沒有MSS,將使用默認值536。MSS Option的Value字段長度固定為16bit,所以MSS最大值為65535(單位Byte)。因此,網絡中所有設備都被要求,必須能夠處理大小小於576Byte的數據包(IP Header + TCP Header + Default MSS 最小值為 576 Byte)
3. IPv4網絡中,MSS的典型取值為1460 ,1460Byte + 20Byte IP Header + 20Byte TCP Header = 1500Byte = 以太網典型MTU;
4. IPv6網絡中,典型MSS取值為1440;另外,如果MSS=65535,表示MSS = PMTU - 60
② .Selective Acknowledgment (SACK) Options
在標准的TCP實現中,使用的是累加式的ACK,例如“ACK Num = n”代表對序列號n以前的Bytes進行確認。但是,顯然,這樣將無法對不連續的Segment進行確認。此外,當出現不連續Segment時,還會導致TCP的接收隊列出現一個“坑”,不將這個坑填上,坑后的數據就無法交付給應用程序。
為解決上述問題,TCP定義了SACK Option,可以使TCP接收者將這個“坑”的位置通告給發送者,讓其對這一段數據進行重傳。
注意:若要使用SACK特性,必須在建立連接時,在SYN Segment中附加上SACK-Permitted Option,以此告知對方自己支持SACK。
SACK-Permitted Option格式如下所示:
Kind = 4
Length = 2
SACK Option通過“Left Edge ~ Right Edge”,指定了一個或多個范圍的Seq Num,稱為SACK Block,指明了處於“坑”后面(或坑之間)的、已成功接收的Bytes。SACK Option格式如下所示
————
Kind
(5)
Length
(可變)
Left Edge of 1st Block
(32bit)
Right Edge of 1st Block
(32bit)
……
……
Left Edge of nst Block
(n≤4)
Right Edge of nst Block
(n≤4)
另外,由於TCP Header最長為60 Byte,因此SACK Option中最多只能包含4個SACK Block
Example(終端A - 終端B)
————
1. 終端A收到了TCP數據流中的Seq Num為0 ~ 1452、2905~4096的字節,但缺少了1453~2904;
2. 終端A向B發送ACK Segment,其中ACK Num=1453、SACK Option=2905~4097,表明它已經收到了數據流中的Seq Num為2905 ~ 4096的字節,但沒有還沒收到1453~2904;
3. 終端B收到這個SACK后,重傳包含Byte 1453~2904的TCP Segment;
4. 終端A向B發送ACK Segment,其中ACK Num=4097,表明它已經收到Seq Num 4097之前的所有字節;
5. 之后,數據通信恢復正常。
③ .Window Scale (WSCALE or WSopt) Option
TCP Header的Window Size字段長度為16bit,因而正常情況下,Window Advertisement最大只能是65535 Bytes;
Window Scale Option用於將TCP Header的Window Size字段從16bit擴展至最多30bit,格式如下所示:
Kind
(3)
Length
(3)
shift.cnt
(范圍0~14)
————
1. shift.cnt的取值范圍為0~14,表示將Window Advertisement的值擴展至“WindowSize × 2s
2. WSopt只能出現在SYN Segment或SYN+ACK Segment中,因此shift.cnt在三次握手之后就會固定下來。
3. 另外,WSopt是雙向獨立的,因此連接的兩個方向可以有不同的Shift.cnt。但是,WSopt必須雙向同時啟用,也就是說,如果SYN中不帶有WSopt,SYN+ACK中也不能出現WSopt;同樣,如果SYN+ACK中不帶有WSopt,那么發起SYN的一端就會當作自己也不曾發送過WSopt。
4. shift.cnt根據接收Buffer的大小,由TCP自動選取。接收Buffer由系統或程序設定。
④ .Timestamps Option and PAWS(Protection against Wrapped Sequence Numbers,防止序列號回繞)
啟用Timestamp Option后,每個TCP Segment中都會帶有Timestamp Option,其中包含了兩個32bit的Timestamp(TSval和TSecr),具體格式如下所示:
Kind
(8)
Length
(10)
Timestamp Value(TSval)
Timestamp Echo Reply(TSecr)
1. TSval指明了發送端在發送TCP Segment時的Timestamp;接收端在對該TCP Segment做ACK時,將TSval值回顯在TSecr字段中。
注意:由於TCP連接是雙向的,接收端在ACK中回顯TSecr時,也會把自己當前的Timestamp放入TSval字段。
2. Timestamp是一個隨時間單調遞增的值,由於TCP接收端只需要在ACK中將TSval簡單地回顯,因此通信雙方並不需要進行時間同步等操作。
3. 通過Timestamp Option,發送端再也不需要在內存中保存發送Segment的時間了,只需要將其放入TSval,然后接收端將其回顯在ACK Segment即可。當發送端收到ACK Segment后,取出TSscr,和當前時間做算術差,即可完成一次RTT的測量。
4. 若非通過Timestamp Option來計算RTT,大部分TCP實現只會以“每個Window采樣一次”的頻率來測算RTT。因此通過Timestamp Option,可以實現更密集的RTT采樣,使RTT的測算更精確。
另外,Timestamp Option還有PAWS(Protection Against Wrapped Sequence Numbers,防止序列號回繞)功能,詳見以下示例
————
1. 假設TCP Window Size為1GB(使用Window Scale),發送者每發送一個Window的數據Timestamp值加100,數據的發送情況如下所示:
時間點
發送數據量
Seq Num
Timestamp
接收
1
0G:1G
0G:1G
0~100
OK
2
1G:2G
1G:2G
100~200
其中某些Segment丟包后重傳
3
2G:3G
2G:3G
200~300
OK
4
3G:4G
3G:4G
300~400
OK
5
4G:5G
0G:1G
400~500
OK
6
5G:6G
1G:2G
500~600
此前丟包的Segment出現了
2. 在時間點2的時候,發生了丟包;在時間點4和5之間,序列號發生了回繞;在時間點6,已經被認為“丟包”的Segment延遲到達了。
3. 由於延時到達的Segment的timestamp為1xx,小於時間點6的有效timestamp(5xx),因此這個Segment會根據PAWS機制丟棄,從而不會對TCP造成影響。
使用TCP Timestamps option (TSopt) 進行RTT采樣。當前大部分操作系統(Linux、Windows)的實現方式如下
User Timeout (UTO) Option
UserTimeout值表明了TCP發送者等待ACK的時間,如果在指定時間內沒收到ACK,就會認為對端掛掉。對於傳統TCP(RFC 793)而言,UserTimeout是本地配置的。RFC 1122建議,當TCP重傳3次后,應該通知應用程序,100s后,應該拆除連接。
通過UTO,可以讓TCP將UserTimeout值“告知”給對端,UTO格式如下所示:
Kind
(28)
Length
(4)
G bit(Granularity bit)
UserTimeout
1. G bit = 1,表示UserTimeout的單位為分鍾;G bit = 0,表示UserTimeout的單位為秒
2. 通過UTO,TCP接收者可以根據“對端的UserTimeout”來調整自己的行為。UserTimeout建議取值為:min(U_Limit,max(Adv_UTO,Remot_UTO,L_Limit))
o U_Limit是本地UserTimeout的最高限制;Adv_UTO是通告出去的UserTimeout;Remot_UTO是對端的UserTimeout;L_Limit是本地UserTimeout的最低限制;
3. 要注意的是,UTO只是用於“告知”,TCP接收者卻不一定要根據對端的UTO值來調整自己的行為。
4. 此外,NAT設備也可以根據UTO來調整連接保活計時器
5. 若使用 = min(U_LIMIT, max(ADV_UTO, REMOTE_UTO, L_LIMIT))
⑥ .Authentication Option (TCP-AO)and TCP MD5 Signature Option(TCP-MD5)
TCP-MD5和TCP-AO主要用於防止TCP欺騙攻擊(TCP Spoofing Attacks)。TCP-MD5是舊標准(RFC 2385),例如BGP、LDP等協議就是以TCP-MD5作為認證手段的。2010年后,IETF建議使用TCP-AO去取代TCP-MD5,然而TCP-AO當前的普及率還很低。
TCP-MD5和TCP-AO的格式如下所示
————
TCP-MD5 Option的MD5 Hash根據以下信息計算:
1.TCP偽頭部
2.TCP頭部(包括Option,checksum設為0)
3.TCP Segment Data
4.密鑰
相對於TCP-MD5,TCP-AO的主要改進之處在於:
1. 支持多種MAC算法
2. 支持帶內的密鑰變更操作
注意:TCP-AO與TCP-MD5一樣,都不包含密鑰分發機制。因此在密鑰分發方面都存在一定風險
---------------------
作者:規速
來源:CSDN
原文:https://blog.csdn.net/hguisu/article/details/12521597
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!