UDP概述
UDP 只在 IP 的数据报服务之上增加了很少一点的功能,即端口的功能和差错检测的功能
UDP 的主要特点
-
UDP 是无连接的
,不需要建立连接,直接发送数据(发送完以后也不需要释放连接) -
UDP 使用尽最大努力交付
,即不保证可靠交付,同时也不使用拥塞控制 -
UDP 是面向报文的
,UDP对应用层交下来的报文,既不合并,也不拆分。这就是说,应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。同理在接收方的UDP,对IP层交上来的UDP用户数据报,在去除首部后就原封不动地交付上层的应用进程。也就是说,UDP一次交付一个完整的报文。所以应用程序必须选择合适大小的报文。
图一
图二
-
UDP 没有拥塞控制
,因此网络出现的拥塞不会使源主机的发送速率降低。这对某些实时应用是很重要的。很多的实时应用(如IP电话、实时视频会议等)要求源主机以恒定的速率发送数据,并且允许在网络发生拥塞时丢失一些数据,但却不允许数据有太大的时延。UDP正好适合这种要求 -
UDP 支持一对一、一对多、多对一和多对多的交互通信
-
UDP 的首部开销小,只有 8 个字节
UDP 的首部格式
用户数据报 UDP 有两个字段:数据字段和首部字段。首部字段有 8 个字节,由 4 个字段组成,每个字段都是两个字节。
- 源端口:源端口号。在需要对方回信时选用。不需要时可用全0
- 目的端口:目的端口号。这在终点交付报文时必须使用
- 长度:UDP用户数据报的长度,其最小值是8(UDP 首部+UDP 用户数据报的数据部分)
- 检验和:检测UDP用户数据报在传输中是否有错。有错就丢弃
当运输层从IP层收到UDP数据报时,就根据首部中的目的端口,把UDP数据报通过相应的端口,上交最后的终点----应用进程。下图是UDP基于端口分用的示意图
如果接收方UDP发现收到的报文中的目的端口号不正确(即不存在对应于该端口号的应用进程),就丢弃该报文,并由网际控制报文协议ICMP发送端口不可达
差错报文给发送方。
检验和
在计算检验和时,临时把伪首部
和 UDP 用户数据报连接在一起。伪首部仅仅是为了计算检验和。所谓伪首部
是因为这种伪首部并不是UDP用户数据报真正的首部。只是在计算检验和时,临时添加在UDP用户数据报前面,得到一个临时的UDP用户数据报。检验和就是按照这个临时的UDP用户数据报来计算的。伪首部既不向下传送也不向上递交,而仅仅是为了计算检验和。下图给出了伪首部各字段的内容。
检验和计算方法
UDP的检验和是把首部和数据部分一起都检验。
在发送方
- 首先是先把全零放入检验和字段。
- 再把伪首部以及UDP用户数据报看成是由许多16位的字串接起来的。若UDP用户数据报的数据部分不是偶数个字节,则要填入一个全零字节(但此字节不发送)。
- 然后按二进制计算出这些16位字的和,然后再对结果取反,将
0->1
,1->0
。将此和的二进制取反结果写入检验和字段后,就发送这样的UDP用户数据报。
在接收方
- 把收到的UDP用户数据报连同伪首部一起(若UDP用户数据报的数据部分不是偶数个字节,则要填入一个全零字节),按二进制反码求这些16位字的和。
- 当无差错时其结果应为全1。否则就表明有差错出现,接收方就应丢弃这个UDP用户数据报(也可以上交给应用层,但附上出现了差错的警告)。
检验和计算过程
这里假定用户数据报的长度是15字节(可以通过IP数据报计算出来),因此要添加一个全0的字节。检验一下在接收端是怎样对检验和进行检验的。不难看出,这种简单的差错检验方法的检错能力并不强,但它的好处是简单,处理起来较快。
校验和详细计算过程
1001100100010011
0000100001101000
+ ----------------
= 1010000101111011
------------------------
1010000101111011
1010101100000011
+ ----------------
= 0100110001111110
------------------------
0100110001111110
0000111000001011
+ ----------------
= 0101101010001001
------------------------
0101101010001001
0000000000010001
+ ----------------
= 0101101010011010
------------------------
0101101010011010
0000000000001111
+ ----------------
= 0101101010101001
------------------------
0101101010101001
0000010000111111
+ ----------------
= 0101111011101000
------------------------
0101111011101000
0000000000001101
+ ----------------
= 0101111011110101
------------------------
0101111011110101
0000000000001111
+ ----------------
= 0101111100000100
------------------------
0101111100000100
0000000000000000
+ ----------------
= 0101111100000100
------------------------
0101111100000100
0101010001000101
+ ----------------
= 1011001101001001
------------------------
1011001101001001
0101001101010100
+ ----------------
= 0000011010011101
------------------------
0000011010011101
0100100101001110
+ ----------------
= 0100111111101011
------------------------
0100111111101011
0100011100000000
+ ----------------
= 1001011011101011
------------------------
1001011011101011
取反 0110100100010010
注意:上述的取反与二进制取反运算有所不同,仅仅是0->1
,1->0
对于接收方,由于校验和字段将0110100100010010取代了原全0的字段,再按照之前的加法,则会得到全1
1001011011101011
0110100100010010
+ ----------------
= 1111111111111111
- 其中伪首部的第3字段是全零;
- 第4字段对应IP首部中的协议字段的值。对于UDP,此协议字段值为17;
- 第5字段是UDP用户数据报的长度。(可以通过IP报文首部计算出来:IP报文长度-IP首部长度,同UDP用户数据报的长度)
因此,这样的检验和,既检查了UDP用户数据报的源端口号和目的端口号以及UDP用户数据报的数据部分,又检查了IP数据报的源IP地址和目的地址。