歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux基礎教程:淺談UDP(數據包長度,收包能力,丟包及進程結構選擇)

Linux基礎教程:淺談UDP(數據包長度,收包能力,丟包及進程結構選擇)

日期:2017/2/25 10:33:30   编辑:Linux教程

UDP數據包長度

UDP數據包的理論長度

udp數據包的理論長度是多少,合適的udp數據包應該是多少呢?從TCP-IP詳解卷一第11章的udp數據包的包頭可以看出,udp的最大包長度是2^16-1的個字節。由於udp包頭占8個字節,而在ip層進行封裝後的ip包頭占去20字節,所以這個是udp數據包的最大理論長度是 2^16-1-8-20=65507。

然而這個只是udp數據包的最大理論長度。首先,我們知道,TCP/IP通常被認為是一個四層協議系統,包括鏈路層、網絡層、運輸層、應用層。 UDP屬於運輸層,在傳輸過程中,udp包的整體是作為下層協議的數據字段進行傳輸的,它的長度大小受到下層ip層和數據鏈路層協議的制約。

MTU相關概念

以太網(Ethernet)數據幀的長度必須在46-1500字節之間,這是由以太網的物理特性決定的。這個1500字節被稱為鏈路層的MTU(最大傳輸單元)。因特網協議允許IP分片,這樣就可以將數據包分成足夠小的片段以通過那些最大傳輸單元小於該數據包原始大小的鏈路了。這一分片過程發生在網絡層,它使用的是將分組發送到鏈路上的網絡接口的最大傳輸單元的值。這個最大傳輸單元的值就是MTU(Maximum Transmission Unit)。它是指一種通信協議的某一層上面所能通過的最大數據包大小(以字節為單位)。最大傳輸單元這個參數通常與通信接口有關(網絡接口卡、串口等)。

在因特網協議中,一條因特網傳輸路徑的“路徑最大傳輸單元”被定義為從源地址到目的地址所經過“路徑”上的所有IP跳的最大傳輸單元的最小值。

需要注意的是,loopbackMTU不受上述限制,查看loopback MTU值:

[root@bogon ~]# cat /sys/class/net/lo/mtu

65536

IP分包udp數據包長度的影響

如上所述,由於網絡接口卡的制約,mtu的長度被限制在1500字節,這個長度指的是鏈路層的數據區。對於大於這個數值的分組可能被分片,否則無法發送,而分組交換的網絡是不可靠的,存在著丟包。IP 協議的發送方不做重傳。接收方只有在收到全部的分片後才能 reassemble並送至上層協議處理代碼,否則在應用程序看來這些分組已經被丟棄。

假定同一時刻網絡丟包的概率是均等的,那麼較大的IP datagram必然有更大的概率被丟棄,因為只要丟失了一個fragment,就導致整個IP datagram接收不到。不超過MTU的分組是不存在分片問題的。

MTU的值並不包括鏈路層的首部和尾部的18個字節。所以,這個1500字節就是網絡層IP數據報的長度限制。因為IP數據報的首部為20字節,所以IP數據報的數據區長度最大為1480字節。而這個1480字節就是用來放TCP傳來的TCP報文段或UDP傳來的UDP數據報的。又因為UDP數據報的首部8字節,所以UDP數據報的數據區最大長度為1472字節。這個1472字節就是我們可以使用的字節數。

當我們發送的UDP數據大於1472的時候會怎樣呢?這也就是說IP數據報大於1500字節,大於MTU。這個時候發送方IP層就需要分片 (fragmentation)。把數據報分成若干片,使每一片都小於MTU。而接收方IP層則需要進行數據報的重組。而更嚴重的是,由於UDP的特性,當某一片數據傳送中丟失時,接收方便無法重組數據報。將導致丟棄整個UDP數據報。因此,在普通的局域網環境下,將UDP的數據控制在1472字節以下為好。

進行Internet編程時則不同,因為Internet上的路由器可能會將MTU設為不同的值。如果我們假定MTU為1500來發送數據的,而途經的某個網絡的MTU值小於1500字節,那麼系統將會使用一系列的機制來調整MTU值,使數據報能夠順利到達目的地。鑒於Internet上的標准 MTU值為576字節,所以在進行Internet的UDP編程時,最好將UDP的數據長度控件在548字節(576-8-20)以內。

UDP丟包

udp丟包是指網卡接收到數據包後,linux內核的tcp/ip協議棧在udp數據包處理過程中的丟包,主要原因有兩個:

1、udp數據包格式錯誤或校驗和檢查失敗。

2、應用程序來不及處理udp數據包。

對於原因1,udp數據包本身的錯誤很少見,應用程序也不可控,本文不討論。

首先介紹通用的udp丟包檢測方法,使用netstat命令,加-su參數。

# netstat -su

Udp:

2495354 packets received

2100876 packets to unknown port received.

3596307 packet receive errors

14412863 packets sent

RcvbufErrors: 3596307

SndbufErrors: 0

從上面的輸出中,可以看到有一行輸出包含了"packet receive errors",如果每隔一段時間執行netstat -su,發現行首的數字不斷變大,表明發生了udp丟包。

Copyright © Linux教程網 All Rights Reserved