UDP协议在IP协议上增加了复用、分用和差错检测功能。UDP的特点:
A)是无连接的。相比于TCP协议,UDP协议在传送数据前不需要建立连接,当然也就没有释放连接。
B)是尽最大努力交付的。也就是说UDP协议无法保证数据能够准确的交付到目的主机。也不需要对接收到的UDP报文进行确认。
C)是面向报文的。也就是说UDP协议将应用层传输下来的数据封装在一个UDP包中,不进行拆分或合并。因此,运输层在收到对方的UDP包后,会去掉首部后,将数据原封不动的交给应用进程。
D)没有拥塞控制。因此UDP协议的发送速率不送网络的拥塞度影响。
E)UDP支持一对一、一对多、多对一和多对多的交互通信。
F)UDP的头部占用较小,只占用8个字节。
UDP报文格式
UDP协议分为首部字段和数据字段,其中首部字段只占用8个字节,分别是个占用两个字节的源端口、目的端口、长度和检验和。
UDP数据报
(1)端口号表示发送进程和接收进程。TCP端口号与UDP端口号是相互独立的。如果TCP和UDP同时提供某种知名服务,两个协议通常选择相同的端口号,只是为了方便,而不是协议本身的要求。
(2)UDP长度字段指的是UDP首部和UDP数据的字节长度。该字段的最小值为8字节(发送一份0字节的UDP数据报是可以的)。这个UDP长度是有冗余的。
(3)UDP数据报长度是全长减去IP首部的长度。
udp校验和的计算原理
Udp校验与tcp校验基本上是一致的。
udp校验需要将ip伪首部、udp报头、udp数据分为16位的字,然后进行累加(如果总长度为奇数个字节,则在最后增添一个位都为0的字节 ),最后对累加的和进行按位取反即可。
Ip伪首部包括源ip地址(4字节)、目的ip地址(4字节)、协议号(两字节)、tcp包长(2字节) ,共14字节。 在进行检验和计算时,会添加一个伪首部一起进行运算。伪首部(占用12个字节)为:4个字节的源IP地址、4个字节的目的IP地址、1个字节的0、一个字节的数字17、以及占用2个字节UDP长度。这个伪首部不是报文的真正首部,只是引入为了计算校验和。相对于IP协议的只计算首部,UDP检验和会把首部和数据一起进行校验。接收端进行的校验和与UDP报文中的校验和相与,如果无差错应该全为1。如果有误,则将报文丢弃或者发给应用层、并附上差错警告。
(1)UDP数据报的长度在检验和计算过程中出现两次。
(2)如果检验和的计算结果为0,则存入的值为全1(65535),这在二进制反码计算中是等效的。如果传送的检验和为0,说明发送端没有计算检验和。
(3)如果发送端没有计算检验和而接收端检测到检验和有差错,UDP数据报就要被丢弃。不产生任何差错报文(当IP层检测到IP首部检验和有差错时也这样做)。
(4)UDP检验和是一个端到端的检验和。它由发送端计算,然后由接收端验证。其目的是为了发现UDP首部和数据在发送端到接收端之间发生的任何改动。
(5)尽管UDP检验和是可选的,但是它们应该总是在用。
(6)UDP检验和(事实上,TCP/IP协议簇中所有的检验和)是简单的16 bit和。它们检测不出交换两个16 bit的差错。
IP分片的原理:
分片和重新组装的过程对传输层是透明的,其原因是当IP数据报进行分片之后,只有当它到达下一站时,才可进行重新组装,且它是由目的端的IP层来完成的。分片之后的数据报根据需要也可以再次进行分片。 IP分片和完整IP报文差不多拥有相同的IP头,ID域对于每个分片都是一致的,这样才能在重新组装的时候识别出来自同一个IP报文的分片。在IP头里面,16位识别号唯一记录了一个IP包的ID(ipid),具有同一个ID的IP分片将会重新组装;而13位片偏移则记录了某IP片相对整个包的位置;而这两个表中间的3位标志则标志着该分片后面是否还有新的分片。这三个域就组成了IP分片的所有信息, 接受方就可以利用这些信息对IP数据进行重新组织。
标识(identification):占16位。IP软件在存储器中维持一个计数器,每产生一个数据报,计数器就加1,并将此值赋给标识字段。
但这个“标识”不是序号,因为IP是无连接服务,数据报不存在按序接收的问题。当数据报由于长度超过网络的MTU而必须分片时,
这个标识字段的值就被复制到所有的数据报片的标识字段中。相同的标识字段的值使分片后的各数据报片最后能正确地重装成为原来的数据报。
标志(flag):占3位,但目前只有两位有意义。
-- 标志字段中的最低位为MF(More Fragment)。MF=1即表示后面“还有分片”的数据报。MF=0表示这已是若干数据报片中的最后一个。
-- 标志字段中间的一位记为DF(Don't Fragment),意思是“不能分片”。只有当DF=0时才允许分片。
片偏移 :占13位。片偏移指出:较长的分组在分片后,某片在原分组中的相对位置。也就是说,相对于用户数据字段的起点,该片
从何处开始。片偏移以8个字节为偏移单位。也就是说,每个分片的长度一定是8字节(64位)的整数倍。
IP分片过程:
IP在从上层接到数据以后,要根据IP地址来判断从那个接口发送数据(通过选路),并进行MTU的查询,如果数据大小超过MTU就进行数据分片。数据的分片是对上层和下层透明,而数据也只是到达目的地还会被重新组装,不过不用担心,IP层提供了足够的信息进行数据的再组装。
(1)对于发送端发送的每份IP数据报,标识字段都包含一个唯一值,该值在数据报分片时被复制到每个片中。
(2)标志字段用其中一个比特来表示“更多的片”。除了最后一片外,其他每个组成数据报的片都要把该比特置1。
(3)片偏移字段指的是该片偏移原始数据报开始处的位置。
说明:
(1)当数据报被分片后,每个片的总长度值要改为该片的长度值。
(2)标志字段中有一个比特称作“不分片”位。如果将这一比特置1,IP将不对数据报进行分片。相反把数据报丢弃并发送一个ICMP差错报文给起始端。
(3)当IP数据报被分片后,每一片都成为一个分组,具有自己的IP首部,并在选择路由时与其他分组独立。当数据报的这些片到达目的端时有可能会失序,但在IP首部中有足够的信息让接收端能正确组装这些数据报片。
(4)在分片时,除最后一片外,其他每一片中的数据部分(除IP首部外的其余部分)必须是8字节的整数倍。
(5)任何运输层首部只出现在第1片数据中。
一个未分片的数据报的分片信息字段全为0,即多个分片标志位为0,并且片偏移量为0。分片一个数据报,需执行以下几个步骤: 检查DF标志位,查明是否允许分片。如果设置了该位,则数据报将被丢弃,并将一个ICMP错误返回给源端。 基于MTU值,把数据字段分成两个部分或者多个部分。除了最后的数据部分外,所有新建数据选项的长度必须为8个字节的倍数。 每个数据部分被放入一个IP数据报。这些数据报的报文头略微修改了原来的报文头。 除了最后的数据报分片外,所有分片都设置了多个分片标志位。 每个分片中的片偏移量字段设为这个数据部分在原来数据报中所占的位置,这个位置相对于原来未分片数据报中的开头处。 如果在原来的数据报中包括了选项,则选项类型字节的高位字节决定了这个信息是被复制到所有分片数据报,还是只复制到第一个数据报。 设置新数据报的报文头字段及总长度字段。 重新计算报文头部校验和字段。
IP报文的重组:
为了重组数据报分片,接收主机在第一个分片到达时分配一个存储缓冲区。这个主机还将启动一个计时器。当数据报的后续分片到达时,数据被复制到缓冲区存储器中片偏移量字段指出的位置。当所有分片都到达时,完整的未分片的原始数据报就被恢复了。处理如同未分片数据报一样继续进行。
如果计时器超时并且分片保持尚未认可状态,则数据报被丢弃。这个计时器的初始值称为IP数据报的生存期值。它是依赖于实现的。一些实现允许对它进行配置。在某些IP主机上可以使用netstat命令列出分片的细节。如TCP/IP for OS/2中的netstat-i命令
5、ICMP不可达差错(需要分片)
发生ICMP不可达差错的另一种情况是(前面讲过端口不一致也会导致ICMP不可达差错),当路由器收到一份需要分片的数据报,而在IP首部又设置了不分片(DF)的标志比特。
如果某个程序需要判断到达目的端的路途中最小MTU是多少(路径MTU发现机制),那么这个差错就可以被该程序使用。报文格式如图11-9所示:
6、最大UDP数据报长度
理论上,IP数据报的最大长度是65535字节(IP首部16比特总长度字段)。去除20字节的IP首部和8字节的UDP首部,UDP数据报中用户数据的最大长度为65507字节。但实际大多数实现所提供的长度比这个最大值小。
(1)应用程序可能会受到其程序接口的限制
socket API提供了一个可供应用程序调用的函数,以设置接收和发送缓存的长度。这个长度与应用程序可以读写的最大UDP数据报的长度直接相关,现在的大部分系统都默认提供可读写大于8192字节的UDP数据报。
(2)限制来自于TCP/IP的内核实现。
可能存在一些实现特性(或差错),使IP数据报长度小于65535字节。
数据报截断:
IP能够发送或接收特定长度的数据报并不意味着接收应用程序可以读取该长度的数据。UDP编程接口允许应用程序指定每次返回的最大字节数。如果接收到的数据报长度大于应用程序所能处理的长度,发生的情况取决于编程接口和实现。例如:Berkeley版socket API对数据报进行截断,并丢弃任何多余的数据。
7、ICMP源站抑制差错
当一个系统(路由器或主机)接收数据报的速度比其处理速度快时,可能产生这个差错。
注意:“可能”产生这个差错。即使一个系统已经没有缓存并丢弃数据报,也不要求它一定要发送源站抑制报文。
8、UDP服务器的设计
对于服务器来说,它启动后处于休眠状态,等待客户请求的到来。对于UDP来说,当客户数据报到达时,服务器苏醒过来,数据报中可能包含来自客户的某种形式的请求消息。
(1)客户IP地址及端口号
IP首部包含源端和目的端IP地址,UDP首部包含了源端和目的端的UDP端口号。当一个应用程序接收到UDP数据报时,操作系统必须告诉它是谁发送了这份消息,即源IP地址和端口号。这个特性允许一个交互UDP服务器对多个客户进行处理。给每个发送请求的客户发回应答。
(2)目的IP地址
一些应用程序需要知道数据报是发送给谁的,即目的IP地址。这要求操作系统从接收到的UDP数据报中将目的IP地址交给应用程序。
(3)UDP输入队列
大多数UDP服务器是交互服务器。这意味着,单个服务器进程对单个UDP端口上(服务器上的名知端口)的所有客户请求进行处理。
通常程序所使用的每个UDP端口都与一个有限大小的输入队列相联系。来自不同客户的差不多同时到达的请求将由UDP自动排队。接收到的UDP数据报以其接收顺序交给应用程序
排队溢出造成内核中的UDP模块丢弃数据报的可能性是存在的。
1)应用程序并不知道其输入队列何时溢出。只是由UDP对超出数据报进行丢弃处理。
2)没有发回任何信息告诉客户其数据报被丢弃。
(4)限制本地IP地址
大多数UDP服务器在创建UDP端点时都使其本地IP地址具有通配符(wildcard)的特点。表明进入的UDP数据报如果其目的地为服务器端口,那么在任何本地接口均可接收到它。
另一方面,当服务器创建端点时,它可以把其中一个主机本地IP地址包括广播地址指定为端点的本地IP地址。只有当目的IP地址与指定的地址相匹配时,进入的UDP数据报才能被送到这个端点。
(5)限制远端IP地址
大多数系统都允许UDP端点对远端地址进行限制,即端点将只能接收特定IP地址和端口号的UDP数据报。
(6)每个端口有多个接收者
大多数系统在某一时刻只允许一个程序端点与某个本地IP地址及UDP端口号相关联。当目的地为该IP地址及端口号的UDP数据报到达主机时,就复制一份传给该端点。
然而,在一个支持多播的系统上,多个端点可以使用同一个IP地址和UDP端口号。
当UDP数据报到达的目的IP地址为广播地址或多播地址,而且在目的IP地址和端口号处有多个端点时,就向每个端点传送一份数据报的复制。如果UDP数据报到达的是一个单播地址,那么只向其中一个端点传送一份数据报的复制。选择哪个端点传送数据取决于各个不同的系统实现。
小结:
(1)UDP是一个简单协议,它向用户进程提供的服务位于IP层之上,包括端口号和可选的检验和。ICMP不可达差错,是新的路径MTU发现功能中的一部分。
(2)对于UDP和ARP之间的接口,大多数的ARP实现在等待ARP应答时只保留最近传送给目的端的数据报。
(3)当系统接收IP数据报的速率超过这些数据报被处理的速率时,系统可能发送ICMP源站抑制差错报文。使用UDP时很容易产生这样的ICMP差错。 |