《TCP/IP协议详解 卷1》--- UDP:用户数据报协议

UDP是一个简单的面向数据报的运输层协议:进程的每个输出操作都正好产生一个UDP数据报,并组装成一份待发送的IP数据报。
这与面向流字符的协议不同,如TCP,应用程序产生的全体数据与真正发送的单个IP数据报可能没有什么联系。
这里写图片描述
UDP不提供可靠性:它把应用程序传给IP层的数据发送出去,但是并不保证它们能到达目的地。
应用程序必须关心IP数据报的长度。如果它超过网络的MTU,那么就要对IP数据报进行分片。

UDP首部
这里写图片描述
端口号表示发送进程和接收进程。
长度字段指的是UDP首部和UDP数据的字节长度。该字段的最小值为8字节(发送一份0字节的UDP数据报是OK)。

UDP检验和
UDP检验和覆盖UDP首部和UDP数据。IP首部的检验和只覆盖IP的首部 ,并不覆盖IP数据报中的任何数据。
UDP的检验和是可选的,而TCP的检验和是必需的。
这里写图片描述
UDP数据报和TCP段都包含一个12字节长的伪首部,它是为了计算检验和而设置的。伪首部包含IP首部一些字段。其目的是让UDP两次检查数据是否已经正确到达目的地。
UDP数据报的长度在检验和计算过程中出现两次。
如果检验和的计算结果为0,则存入的值为全1(65535),这在二进制反码计算中是等效的。如果传送的检验和为0,说明发送端没有计算检验和。
UDP检验和是可选的。

IP分片
任何时候IP层接收到一份要发送的IP数据报时,它要判断向本地哪个接口发送数据(选路),并查询该接口获得其MTU。IP把MTU与数据报长度进行比较,如果需要则进行分片。分片可以发生在原始发送端主机上,也可以发生在中间路由器上。

把一份IP数据报分片以后,只有到达目的地才进行重新组装。已经分片过的数据报有可能会再次进行分片(可能不止一次)。IP首部中包含的数据为分片和重新组装提供了足够的信息。

IP首部标志字段用其中一个比特来表示“更多的片”。除了最后一片外,其他每个组成数据报的片都要把该比特置 1。片偏移字段指的是该片偏移原始数据报开始处的位置。另外,当数据报被分片后,每个片的总长度值要改为该片的长度值。
标志字段中有一个比特称作“不分片”位。如果将这一比特置1,IP将不对数据报进行分片。相反把数据报丢弃并发送一个ICMP差错报文(“需要进行分片但设置了不分片比特”)给起始端。

当IP数据报被分片后,每一片都成为一个分组,具有自己的IP首部,并在选择路由时与其他分组独立。这样,当数据报的这些片到达目的端时有可能会失序,但是在IP首部中有足够的信息让接收端能正确组装这些数据报片。

尽管IP分片过程看起来是透明的,但有一点让人不想使用它:即使只丢失一片数据也要重传整个数据报。

使用UDP很容易导致IP分片。

IP数据报是指IP层端到端的传输单元(在分片之前和重新组装之后),分组是指在IP层和链路层之间传送的数据单元。一个分组可以是一个完整的IP数据报,也可以是IP数据报的一个分片。

20+8+1472=1501>1500,需要分片。在分片时,除最后一片外,其他每一片中的数据部分(除IP首部外的其余部分)必须是8字节的整数倍。1472+8=1480,是8的整数倍。
这里写图片描述

ICMP不可达差错(需要分片)
发生ICMP不可达差错的另一种情况是,当路由器收到一份需要分片的数据报,而在IP首部又设置了不分片(DF)的标志比特。如果某个程序需要判断到达目的端的路途中最小MTU是多少 — 称作路径MTU发现机制,那么这个差错就可以被该程序使用。
这里写图片描述

用Traceroute确定路径MTU
尽管大多数的系统不支持路径MTU发现功能,但可以很容易地修改traceroute程序,用它来确定路径MTU。
可用traceroute.pmtu确定MTU。
这里写图片描述
路由器返回的MTU值为296。

UDP和ARP之间的交互作用

每个数据报片都会引发一个ARP请求。
在接收到第一个ARP应答时,只发送最后一个数据报片。在大多数的实现中,在等待一个ARP应答时,只将最后一个报文发送给特定目的主机。

最大UDP数据报长度

理论上,IP数据报的最大长度是65535字节,这是由IP首部16比特总长度字段所限制的。去除20字节的IP首部和8个字节的UDP首部,UDP数据报中用户数据的最长长度为65507字节。但是,大多数实现所提供的长度比这个最大值小。

两个限制因素。第一,应用程序可能会受到其程序接口的限制。 socket API提供了一个可供应用程序调用的函数,以设置接收和发送缓存的长度。对于UDP socket,这个长度与应用程序可以读写的最大UDP数据报的长度直接相关。现在的大部分系统都默认提供了可读写大于8192字节的UDP数据报(使用这个默认值是因为 8192是NFS读写用户数据数的默认值)。
第二个限制来自于TCP/IP的内核实现。可能存在一些实现特性(或差错),使IP数据报长度小于65535字节。

主机必须能够接收最短为576字节的IP数据报。在许多UDP应用程序的设计中,其应用程序数据被限制成512字节或更小,因此比这个限制值小。

ICMP源站抑制差错
当一个系统(路由器或主机)接收数据报的速度比其处理速度快时,可能产生这个差错。
这里写图片描述
TCP接受源站抑制差错报文,并将放慢在该连接上的数据传输速度。
如果采用UDP协议,那么BSD实现通常忽略其接收到的源站抑制报文,其部分原因在于,在接收到源站抑制差错报文时,导致源站抑制的进程可能已经中止了。

UDP服务器的设计

UDP输入队列:通常程序所使用的每个 U D P端口都与一个有限大小的输入队列相联系。排队溢出造成内核中的 UDP模块丢弃数据报的可能性是存在的。

限制本地IP地址:大多数UDP服务器在创建UDP端点时都使其本地IP地址具有通配符( * )的特点。这就表明进入的 UDP数据报如果其目的地为服务器端口,那么在任何本地接口均可接收到它。
当服务器创建端点时,它可以把其中一个主机本地IP地址包括广播地址指定为端点的本地IP地址。只有当目的IP地址与指定的地址相匹配时,进入的UDP数据报才能被送到这个端点。
有可能在相同的端口上启动不同的服务器,每个服务器具有不同的本地IP地址。但是,一般必须告诉系统应用程序重用相同的端口号没有问题。
如果存在一个含星号的IP地址,那么就隐含了一种优先级关系。如果为端点指定了特定IP地址,那么在匹配目的地址时始终优先匹配该IP地址。只有在匹配不成功时才使用含星号的端点。

限制远端IP地址:netstat输出结果中,远端IP地址和远端端口号都显示为 * . *,其意思是该端点将接受来自任何IP地址和任何端口号的UDP数据报。大多数系统允许UDP端点对远端地址进行限制,使得端点将只能接收特定IP地址和端口号的UDP数据报。
伯克利派生系统中,如果在指定远端地址时没有选择本地地址,那么将自动选择本地地址。
这里写图片描述

每个端口有多个接收者:当UDP数据报到达的目的IP地址为广播地址或多播地址,而且在目的IP地址和端口号处
有多个端点时,就向每个端点传送一份数据报的复制(端点的本地IP地址可以含有星号,它可匹配任何目的IP地址)。但是,如果UDP数据报到达的是一个单播地址,那么只向其中一个端点传送一份数据报的复制。选择哪个端点传送数据取决于各个不同的系统实现。

猜你喜欢

转载自blog.csdn.net/u012319493/article/details/80935361