操作系统 > Linux > 文章内容

Linux基础教程:浅谈UDP(数据包长度,收包能力,丢包及进程结构选择)

2016-2-27编辑:ljnbset

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丢包。

Linux基础教程:Linux性能监控-NetworkIO

热点推荐

登录注册
触屏版电脑版网站地图