tcp/ip詳解(轉)


與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
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM