天天看點

動手學習TCP:資料傳輸(轉)

前面的文章介紹了TCP狀态變遷,以及TCP狀态變遷圖中的一些特殊狀态。

本文主要看看TCP資料傳輸過程中需要了解的一些重要點:

MSS(Maximum Segment Size)

Seq号和Ack号的計算

TCP半連接配接

在開始介紹上面列出的内容之前,先看看實驗程式的運作。

首先,修改了"BuildTcpPacket"這個函數,增加了兩個功能:

正常情況下TCP首部是20個位元組,但是TCP首部支援一些特殊"Options"(MSS就是其中一個);是以,第一個改動就是支援建立帶特殊選項的TCP包

第二個改動是可以通過參數設定為TCP包增加Payload,這樣就可以通過TCP包傳輸資料了。

動手學習TCP:資料傳輸(轉)
動手學習TCP:資料傳輸(轉)

代碼其餘的改動發生在"PacketHandler"函數中:

增加了對于"ESTABLISHED"狀态下收到資料包的處理,主要作用就是發送一個[ACK]包對收到的資料包進行确認。

動手學習TCP:資料傳輸(轉)
動手學習TCP:資料傳輸(轉)

代碼修改好之後,運作代碼。

通過console端可以看到,在連接配接為"ESTABLISHED"狀态下,用戶端收到的來自服務端的位元組數。

動手學習TCP:資料傳輸(轉)

通過Wireshark抓包可以看到,在連接配接建立請求包[SYN]中增加了MSS的設定,并且以後的資料傳出中,TCP資料包的payload長度最大就是MSS的值。

動手學習TCP:資料傳輸(轉)

下面就開始介紹上面實驗中涉及的TCP資料傳輸的知識點。

在網絡上傳輸的資料包是有大小限制,這裡就需要知道TCP分段和IP分片的概念了。

跟這兩個概念緊密相關的就是MSS(Maximum Segment Size)和MTU(Maximum Transmission Unit)這兩個名額了,這兩個名額的值大小直接決定了TCP分段和IP分片。

下面分别看看MSS和MTU。

首先來看看MTU。

以太網和802.3對資料幀的長度都有一個限制,最大值分别是1500和1492個位元組。鍊路層的這個名額稱作MTU(注意MTU是鍊路層的概念),不同類型的網絡大多數都有一個上限。

如果網絡層(IP層)有一個資料報需要傳輸,且資料的長度比鍊路層的 MTU還大,那麼網絡層(IP層)就要進行分片(fragmentation),把資料報分成若幹片,保證每一個分片都小于MTU;目的端的網絡層(IP層)會對收到的分片進行重新組裝。

也就是說,分片和重新組裝過程發生在網絡層(IP層),是以對運輸層(TCP/UDP)是透明的。

下面看看通過ping指令示範IP分片,ping指令屬于ICMP(Internet Control Messages Protocol)協定:

動手學習TCP:資料傳輸(轉)

Wireshark的結果為下,這5000個位元組的資料被分别放在了四個IP分片中,每個分片(最後一個分片除外)中的資料長度等于1480(1500 – 20[IP header]):

動手學習TCP:資料傳輸(轉)

IP分片的問題:IP分片有一個很大的問題,由于IP層本身沒有逾時重傳機制,即使隻丢失一片資料也要重新傳整個資料報。也就是說,對于上面截圖中的4個Frame,任何一個丢失了,另外3個都需要進行重傳。

使用UDP和ICMP的時候很容易導緻IP分片,因為UDP和ICMP是不考慮MTU和分片的,而是把這些工作都丢給了網絡層(IP層);但是,為了減少IP分片對TCP的影響,在TCP中提出了MSS來試圖避免IP分片。

MSS就是TCP資料包每次能夠傳輸的最大資料分段。

為了達到最佳的傳輸效能TCP協定在建立連接配接的時候通常要協商雙方的MSS值,這個值TCP協定在實作的時候往往用MTU值代替(需要減去IP資料包首部的大小20Bytes和TCP資料段的首部20Bytes),是以往往MSS為1460。通訊雙方會根據雙方提供的MSS值得最小值确定為這次連接配接的最大MSS值。

回到本文開始的例子,在建立TCP連接配接的時候,用戶端指定了MSS為800,服務端指定的MSS為1460。經過協商後,雙方采用了較小的MSS,是以以後的資料包長度最到為800位元組。TCP就是通過這種方式來避免IP分片的。

再看一個MSS的例子,通過Wireshark抓取了一段HTTP請求,通過GET方法請求jquery的一組資料包。

通過下面可以看到,當應用層有一個超過MSS的資料需要發送的時候,TCP會把應用層的資料分成多個TCP分段然後發送出去。每一個分段包都包含TCP首部,然後傳遞給網絡層進一步增加IP首部。

動手學習TCP:資料傳輸(轉)

通過上面可以看到TCP分段和IP分片有下面的主要差別:

TCP分段發生在傳輸層,分段的依據是MSS;IP分片發生在網絡層,分片的依據是MTU

TCP分段是在傳輸層完成,并在傳輸層進行重組;IP分片由網絡層完成,也在網絡層進行重組

TCP傳輸的可靠性是通過Seq和Ack号來進行保證的,是以可以看出Seq和Ack号的重要性。

文章開始的實驗中,另一個需要注意的地方就是Seq和Ack号的變化。

在前面TCP連接配接的相關文章中已經介紹了連接配接建立和終止時候Seq和Ack号的變化,可以總結得到下面公式:

确認包的Ack = 待确認包(特殊标志包)的Seq + 1

從Wireshark的截圖中可以看到在資料傳輸中Seq和Ack号的變化。

動手學習TCP:資料傳輸(轉)

對于資料包的确認,可以使用下面的方式進行計算:

确認包的Ack = 待确認資料包的Seq + 待确認資料包的資料長度(Len)

在介紹TCP終止連接配接的時候,提到了由于TCP是全雙工的,是以需要經過四次揮手才能關閉TCP連接配接。

TCP中有一個半連接配接的概念,就是TCP連接配接的一端在結束它的發送後,還能接收來自另一端資料。

還是回到文章開始的例子,服務端發出了終止TCP連接配接的請求[FIN, ACK],用戶端進行了确認,到此服務端到用戶端方向的TCP連接配接就關閉了。

但是,随後用戶端向服務端發送了一段長度為480位元組的資料,然後才關閉用戶端到服務端方向的TCP連接配接。

動手學習TCP:資料傳輸(轉)

本文主要介紹了TCP資料傳輸中的幾個重要的概念。

Seq号和Ack号

通過這篇文章,一定能很好的認識TCP分段和IP分片的差別,以及MSS和MTU的關系

http://www.cnblogs.com/wilber2013/p/4853674.html

繼續閱讀