TCP、UDP數據包分析

TCP、UDP數據包分析

   一、概述

首先要看TCP/IP協議,涉及到四層:鏈路層,網絡層,傳輸層,應用層。   
其中以太網(Ethernet)的數據幀在鏈路層   
IP包在網絡層   
TCP或UDP包在傳輸層   
TCP或UDP中的數據(Data)在應用層   
它們的關係是 數據幀{IP包{TCP或UDP包{Data}}}   

    不一樣的協議層對數據包有不一樣的稱謂,在傳輸層叫作段(segment),在網絡層叫作數據報(datagram),在鏈路層叫作幀(frame)。數據封裝成幀後發到傳輸介質上,到達目的主機後每層協議再剝掉相應的首部,最後將應用層數據交給應用程序處理。編程

 

在應用程序中咱們用到的Data的長度最大是多少,直接取決於底層的限制。   
咱們從下到上分析一下:   
1.在鏈路層,由以太網的物理特性決定了數據幀的長度爲(46+18)-(1500+18),其中的18是數據幀的頭和尾,也就是說數據幀的內容最大爲1500(不包括幀頭和幀尾),即MTU(Maximum Transmission Unit)爲1500;  
2.在網絡層,由於IP包的首部要佔用20字節,因此這的MTU爲1500-20=1480; 
3.在傳輸層,對於UDP包的首部要佔用8字節,因此這的MTU爲1480-8=1472;   
因此,在應用層,你的Data最大長度爲1472。當咱們的UDP包中的數據多於MTU(1472)時,發送方的IP層須要分片fragmentation進行傳輸,而在接收方IP層則須要進行數據報重組,因爲UDP是不可靠的傳輸協議,若是分片丟失致使重組失敗,將致使UDP數據包被丟棄。  
從上面的分析來看,在普通的局域網環境下,UDP的數據最大爲1472字節最好(避免分片重組)。   
但在網絡編程中,Internet中的路由器可能有設置成不一樣的值(小於默認值),Internet上的標準MTU值爲576,因此Internet的UDP編程時數據長度最好在576-20-8=548字節之內。
 服務器

二、TCP、UDP數據包最大值的肯定     網絡

        UDP和TCP協議利用端口號實現多項應用同時發送和接收數據。數據經過源端口發送出去,經過目標端口接收。有的網絡應用只能使用預留或註冊的靜態端口;而另一些網絡應用則可使用未被註冊的動態端口。由於UDP和TCP報頭使用兩個字節存放端口號,因此端口號的有效範圍是從0到65535。動態端口的範圍是從1024到65535。  函數

        MTU最大傳輸單元,這個最大傳輸單元實際上和鏈路層協議有着密切的關係,EthernetII幀的結構DMAC+SMAC+Type+Data+CRC因爲以太網傳輸電氣方面的限制,每一個以太網幀都有最小的大小64Bytes最大不能超過1518Bytes,對於小於或者大於這個限制的以太網幀咱們均可以視之爲錯誤的數據幀,通常的以太網轉發設備會丟棄這些數據幀。工具

        因爲以太網EthernetII最大的數據幀是1518Bytes這樣,刨去以太網幀的幀頭(DMAC目的MAC地址48bits=6Bytes+SMAC源MAC地址48bits=6Bytes+Type域2Bytes)14Bytes和幀尾CRC校驗部分4Bytes那麼剩下承載上層協議的地方也就是Data域最大就只能有1500Bytes這個值咱們就把它稱之爲MTU。測試

 

UDP 包的大小就應該是 1500 - IP頭(20) - UDP頭(8) = 1472(Bytes)
TCP 包的大小就應該是 1500 - IP頭(20) - TCP頭(20) = 1460 (Bytes)3d

 

注*PPPoE所謂PPPoE就是在以太網上面跑「PPP」。隨着寬帶接入(這種寬帶接入通常爲Cable Modem或者xDSL或者以太網的接入),由於以太網缺少認證計費機制而傳統運營商是經過PPP協議來對撥號等接入服務進行認證計費的,因此引入PPPoE。PPPoE致使MTU變小了以太網的MTU是1500,再減去PPP的包頭包尾的開銷(8Bytes),就變成1492。不過目前大多數的路由設備的MTU都爲1500。路由

 

        若是咱們定義的TCP和UDP包沒有超過範圍,那麼咱們的包在IP層就不用分包了,這樣傳輸過程當中就避免了在IP層組包發生的錯誤;若是超過範圍,既IP數據報大於1500字節,發送方IP層就須要將數據包分紅若干片,而接收方IP層就須要進行數據報的重組。更嚴重的是,若是使用UDP協議,當IP層組包發生錯誤,那麼包就會被丟棄。接收方沒法重組數據報,將致使丟棄整個IP數據報。UDP不保證可靠傳輸;可是TCP發生組包錯誤時,該包會被重傳,保證可靠傳輸。開發

        UDP數據報的長度是指包括報頭和數據部分在內的總字節數,其中報頭長度固定,數據部分可變。數據報的最大長度根據操做環境的不一樣而各異。從理論上說,包含報頭在內的數據報的最大長度爲65535字節(64K)。網絡編程

       咱們在用Socket編程時,UDP協議要求包小於64K。TCP沒有限定,TCP包頭中就沒有「包長度」字段,而徹底依靠IP層去處理分幀。這就是爲何TCP經常被稱做一種「流協議」的緣由,開發者在使用TCP服務的時候,沒必要去關心數據包的大小,只需講SOCKET看做一條數據流的入口,往裏面放數據就是了,TCP協議自己會進行擁塞/流量控制。 

       不過鑑於Internet(非局域網)上的標準MTU值爲576字節,因此建議在進行Internet的UDP編程時,最好將UDP的數據長度控制在548字節 (576-8-20)之內。

 

三、TCP、UDP數據包最小值的肯定

     在用UDP局域網通訊時,常常發生「Hello World」來進行測試,可是「Hello World」並不知足最小有效數據(64-46)的要求,爲何小於18個字節,對方仍然可用收到呢?由於在鏈路層的MAC子層中會進行數據補齊,不足18個字節的用0補齊。但當服務器在公網,客戶端在內網,發生小於18個字節的數據,就會出現接收端收不到數據的狀況。

       以太網EthernetII規定,以太網幀數據域部分最小爲46字節,也就是以太網幀最小是6+6+2+46+4=64。除去4個字節的FCS,所以,抓包時就是60字節。當數據字段的長度小於46字節時,MAC子層就會在數據字段的後面填充以知足數據幀長不小於64字節。因爲填充數據是由MAC子層負責,也就是設備驅動程序。不一樣的抓包程序和設備驅動程序所處的優先層次可能不一樣,抓包程序的優先級可能比設備驅動程序更高,也就是說,咱們的抓包程序可能在設備驅動程序尚未填充不到64字節的幀的時候,抓包程序已經捕獲了數據。所以不一樣的抓包工具抓到的數據幀的大小可能不一樣。下列是本人分別用wireshark和sniffer抓包的結果,對於TCP 的ACK確認幀的大小一個是54字節,一個是60字節,wireshark抓取時沒有填充數據段,sniffer抓取時有填充數據段。

       

四、實際應用

        用UDP協議發送時,用sendto函數最大能發送數據的長度爲:65535- IP頭(20) - UDP頭(8)=65507字節。用sendto函數發送數據時,若是發送數據長度大於該值,則函數會返回錯誤。  

        用TCP協議發送時,因爲TCP是數據流協議,所以不存在包大小的限制(暫不考慮緩衝區的大小),這是指在用send函數時,數據長度參數不受限制。而實際上,所指定的這段數據並不必定會一次性發送出去,若是這段數據比較長,會被分段發送,若是比較短,可能會等待和下一次數據一塊兒發送。

相關文章
相關標籤/搜索