TCP傳輸數據初探


本文通過一次通信實例對使用TCP傳輸控制協議傳輸數據時可能遇到的問題進行探討。

假設有通信雙方,記發送方為A,接收方為B,信息分別如下:

A:32位linux操作系統,IP地址是172.16.1.216,只有eth0一塊網卡,其MAC為00:0C:29:2F:50:B8,為虛擬機。

B:64位linux操作系統,IP地址是10.10.1.153,只有eth0一塊網卡,其MAC為00:50:56:81:58:27,為實體機。

實驗過程

A往B發送255包數據,每包數據的長度為100字節,每個字節的值是當前包的序號。在B端對整個通信過程進行抓包。

實驗結果

除TCP建連斷連數據包外,B總共接收到的有效數據包有20個,序號分別從3至22。下圖是抓包結果部分截圖。

下表是根據抓包結果整理的各個數據包的詳細信息。

序號 包大小 數據長度 數據內容
3 166 100 01 * 100
4 1514 1448 (02 ~ 0f) * 100 + 10 * 48
5 1514 1448 10 * 52 + (11 ~ 1d) * 100 + 1e * 96
6 1514 1448 1e * 4 + (1f ~ 2c) * 100 + 2d * 44
7 1514 1448 2d * 56 + (2e ~ 3a) * 100 + 3b * 92
8 1514 1448 3b * 8 + (3c ~ 49) * 100 + 4a * 40
9 1514 1448 4a * 60 + (4b ~ 57) * 100 + 58 * 88
10 1514 1448 58 * 12 + (59 ~ 66) * 100 + 67 * 36
11 1514 1448 67 * 64 + (68 ~ 74) * 100 + 75 * 84
12 82 16 75 * 16
13 1514 1448 db * 64 + (dc ~ e8) * 100 + e9 * 84
14 1514 1448 e9 * 16 + (ea ~ f7) * 100 + f8 * 32
15 834 768 f8 * 68 + (f9 ~ ff) * 100
16 1514 1448 (76 ~ 83) * 100 + 84 * 48
17 1514 1448 84 * 52 + (85 ~ 91) * 100 + 92 * 96
18 1514 1448 92 * 4 +  (93 ~ a0) * 100 + a1 * 44
19 1514 1448 a1 * 56 + (a2 ~ ae) * 100 + af * 92
20 1514 1448 af * 8 + (b0 ~ bd) * 100 + be * 40
21 1514 1448 be * 60 + (bf ~ cb) * 100 + cc * 88
22 1514 1448 cc * 12 + (cd ~ da) * 100 + db * 36

 說明:從結果可知,在發送第12包數據后,部分數據未被成功接收到,第16至22包為重傳數據包。

從表中數據容易看出,每個數據包在應用數據的前面都有額外的66個字節,這66個字節從前往后分別是鏈路層、網絡層和傳輸層添加的消息頭(封包),各個消息頭長度分別為14字節、20字節和32字節。

下圖說明了數據進入協議棧時的封裝過程。

 為方便說明起見,下面以序號為5的數據包為例,分別對各層封包進行說明。

以太網首部內容如下:

 以太網首部占14個字節,包含了源地址和目的地址網卡MAC信息,其中前6個字節為目的網卡的MAC,這里是00:50:56:81:58:27,中間6個字節為源網卡的MAC,這里是00:0f:e2:60:8c:f0(與實際不符,多次測試發現是由於機器為虛擬機導致),最后兩個字節代表協議類型,這里是0800,表示類型為IP協議。

一般地,鏈路層從網絡層收到數據后,會在數據前添加目的MAC、源網卡MAC以及網絡層采用的協議類型,在數據后添加4字節的CRC校驗結果,用於幀內后續字節差錯的循環冗余碼校驗。封包過程示意圖如下:

由於數據包尾部的4字節CRC校驗數據是在數據進入物理線路時加上的,而tcpdump、wireshark等抓包工具工作在鏈路層之下、物理線路之上,因此在抓包結果中沒有體現。另外提一下,如果發送端和接收端布署在同一台機器上,通過回環鏈路進行通信,那么抓包結果中鏈路層是沒有數據的,因為數據只到網絡層,不經過鏈路層。

以下是第5包數據IP首部截圖。

從截圖可以看出,IP首部占20個字節,第一個字節的高四位為4,表示協議版本為IPv4,低四位為5,表示本IP數據報為普通數據報,不含任何選項(首部占20個字節)。IP首部的最后8個字節中前4個字節表示源IP地址,這里是ac 10 01 d8,轉換成點分十進制表示方式后為172.16.1.216,后4個字節表示目的IP地址,這里是0a 0a 01 99,對應的點分十進制形式為10.10.1.153。一般地,IP數據報的格式及首部中各字段的含義如下圖所示。

下面是第5包數據的TCP首部截圖。

 該數據包的TCP首部占32字節,前兩字節表示源應用程序使用的端口號,這里是33164,第3、4字節表示目的應用程序使用的端口號,這里是9527。一般地,TCP包的數據格式及首部各字段含義如下圖所示。

縱觀整個通信過程,容易看出只有少數幾個數據包的大小不規則(開始、結束以及出現錯誤重傳時),正常情況下每包數據包含1448字節的應用層數據,下面對此做簡單解釋。

以太網對數據幀的長度有限制,其最大值為1500字節,鏈路層的這個特性被稱作MTU,即最大傳輸單元。除去20字節的IP首部和32字節的TCP首部后,就剩下1448字節的應用數據了。與此相關的另一個參數是MSS(Maximum Segment Size,最大分段大小),表示TCP數據包每次能夠傳輸的最大數據分段。為了達到最佳傳輸效能,TCP協議在建立連接時通常要協商雙方的MSS值,TCP在實現的時候這個值往往用MTU值代替(需要減去IP數據包首部的20字節和TCP數據段首部的20字節,即1460)。下圖為本次實驗的SYN包信息。

從抓包結果還可以看出,雖然發送端分255次發出數據,每次發送100字節,但接收端並不是接收到255包數據,而是只收到20包,各包大小有差異,多數為1448字節,但通信內容都能按順序准確無誤地到達接收端。這是為何?一方面,TCP為了提高傳輸效率,采用優化算法,發送方往往要收集到足夠多的數據或者等待了足夠長的時間后才將數據打成一包發出去;另一方面,如果IP層有一個數據報要傳,且其長度比鏈路層的MTU還大,那么IP層就會把數據分成若干片,使每一片數據長度都小於MTU。

參考資料:《TCP/IP協議詳解卷1:協議》


免責聲明!

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



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