(一)UDP概述
UDP 仅在IP的数据报服务之上增加了两个最基本的服务:复用和分用以及差错检测。如果应用开发者选择UDP而非 TCP,那么应用程序几乎直接与IP打交道。为什么应用开发者宁愿在UDP 之上构建应用,也不选择 TCP?既然 TCP 提供可靠的服务,而UDP不提供,那么TCP总是首选吗?答案是否定的,因为有很多应用更适合用UDP,主要因为UDP具有如下优点:
-
UDP 无须建立连接。因此UDP 不会引入建立连接的时延。试想如果 DNS 运行在TCP 而
非 UDP 上,那么 DNS 的速度会慢很多。HTTP 使用 TCP 而非 UDP,是因为对于基于文
本数据的Web网页来说,可靠性是至关重要的。 -
无连接状态。TCP需要在端系统中维护连接状态。此连接状态包括接收和发送缓存、拥
塞控制参数和序号与确认号的参数。而UDP不维护连接状态,也不跟踪这些参数。因此.
某些专用应用服务器使用UDP时,一般都能支持更多的活动客户机。 -
分组首部开销小。TCP有20B的首部开销,而UDP仅有8B的开销。
-
应用层能更好地控制要发送的数据和发送时间。UDP 没有拥塞控制,因此网络中的拥塞不会影响主机的发送效率。某些实时应用要求以稳定的速度发送,能容忍一些数据的丢失,但不允许有较大的时延,而UDP 正好满足这些应用的需求。
-
UDP支持一对一、一对多、多对一和多对多的交互通信。
UDP 常用于一次性传输较少数据的网络应用,如 DNS、SNMP等,因为对于这些应用,若采用TCP,则将为连接创建、维护和拆除带来不小的开销。UDP也常用于多媒体应用(如IP电话、实时视频会议、流媒体等),显然,可靠数据传输对这些应用来说并不是最重要的,但TCP的拥塞控制会导致数据出现较大的延迟,这是它们不可容忍的。
UDP 不保证可靠交付,但这并不意味着应用对数据的要求是不可靠的,所有维护可靠性的工作可由用户在应用层来完成。应用开发者可根据应用的需求来灵活设计自己的可靠性机制。
UDP是面向报文的。发送方UDP对应用层交下来的报文,在添加首部后就向下交付给IP层,一次发送一个报文,既不合并,也不拆分,而是保留这些报文的边界;接收方UDP对IP层交上来UDP数据报,在去除首部后就原封不动地交付给上层应用进程,一次交付一个完整的报文。因此报文不可分割,是UDP数据报处理的最小单位。因此,应用程序必须选择合适大小的报文,若报文太长,UDP 把它交给 IP层后,可能会导致分片;若报文太短,UDP把它交给IP层后,会使IP数据报的首部的相对长度太大,两者都会降低IP层的效率。
(二)UDP 的首部格式
UDP 数据报包含两部分:UDP首部和用户数据。UDP首部有8B,由4个字段组成,每个字
段的长度都是2B,如下图所示。各字段意义如下:
源端口:源端口号。在需要对方回信时选用,不需要时可用全 0。
目的端口:目的端口号。这在终点交付报文时必须使用到。
长度:UDP 数据报的长度(包括首部和数据),其最小值是8(仅有首部)。
校验和。检测UDP 数据报在传输中是否有错。有错就丢弃。该字段是可选的,当源主机
不想计算校验和时,则直接令该字段为全0。
传输层从IP层收到UDP数据报时,就根据首部中的目的端口,把UDP数据报通过相应的端口上交给应用进程,如下图所示,
如果接收方UDP发现收到的报文中的目的端口号不正确(即不存在对应于端口号的应用进程),那么就丢弃该报文,并由ICMP发送“端口不可达”差错报文给发送方。
(三)UDP校验
在计算校验和时,要在 UDP 数据报之前增加 12B 的伪首部,伪首部并不是UDP 的真正首部.只是在计算校验和时,临时添加在UDP数据报的前面,得到一个临时的UDP数据报。校验和就是按照这个临时的UDP 数据报来计算的。伪首部既不向下传送又不向上递交,而只是为了计算校验和。下图给出了 UDP 数据报的伪首部各字段的内容。
17:封装UDP报文的IP数据报首部协议段是17。
UDP长度:UDP首部8B+数据部分长度(不包括伪首部)。
UDP 校验和的计算方法和IP数据报首部校验和的计算方法相似。但不同的是,IP数据报的校验和只检验IP数据报的首部,但UDP的校验和则检查首部和数据部分。
发送方首先把全零放入校验和字段并添加伪首部,然后把UDP数据报视为许多16位的字串接起来。若UDP数据报的数据部分不是偶数个字节,则要在数据部分末尾填入一个全零字节(但此字节不发送)。然后按二进制反码计算出这些16位字的和,将此和的二进制反码写入校验和字段,并发送。接收方把收到的UDP 数据报加上伪首部(如果不为偶数个字节,那么还需要补上全零字节)后,按二进制反码求这些16位字的和。当无差错时其结果应为全1,否则就表明有差错出现,接收方就应该丢弃这个UDP数据报。
图5.5给出了一个计算UDP校验和的例子。本例中,UDP数据报的长度是15B(不含伪首部),因此需要添加一个全0字节。
注意:
校验时,若 UDP 数据报部分的长度不是偶数个字节,则需填入一个全0字节,如图 5.5
所示。但是此字节和伪首部一样,是不发送的。如果 UDP 校验和校验出 UDP 数据报是错误的,那么可以丢弃,也可以交付给上层,但
是需要附上错误报告,即告诉上层这是错误的数据报。通过伪首部,不仅可以检查源端口号、目的端口号和UDP用户数据报的数据部分,还可
以检查 IP 数据报的源 IP地址和目的地址。这种简单的差错校验方法的校错能力并不强,但它的好处是简单、处理速度快。