UDP 协议

协议简介

UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768 是UDP的正式规范。UDP在IP报文的协议号是17。

用户数据保协议(User Datagram Protocol,UDP)是开放系统互联模型(Open System Interconnection,OSI)中传输层协议的一种,是一种保留消息边界的简单的面向数据报的协议。

UDP不提供差错纠正、队列管理、重复消除、流量控制和拥塞控制,但提供差错检测(包含我们在传输层中碰到的第一个真实的端到端(end-to-end)校验和)。这种协议自身提供最小功能,因此使用它的应用程序要做许多关于数据报如何发送和处理的控制工作。想要保证数据被可靠传递或正确排序,应用程序必须自己实现这些保护功能。

UDP和TCP的相同与不同

Internet 的传输层有两个主要协议,互为补充。无连接的是 UDP,它除了给应用程序发送数据包功能并允许它们在所需的层次上架构自己的协议之外,几乎没有做什么特别的事情。面向连接的是 TCP,该协议几乎做了所有的事情。

两者的共同点

UDP协议与TCP协议一样用于处理数据包,在OSI模型中,两者都位于传输层,处于IP协议的上一层。

两者的不同点

  • UDP无连接,TCP有连接

    1.UDP无连接即发送数据之前源端和终端不需要建立连接;当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上,所以在时间上不存在建立连接需要的时延;
    2.空间上不维护连接状态,也不跟踪接收和发送缓存,拥塞控制参数和序号与确认号的参数。
    3.开销小,时间和空间上都具有优势。

    1.TCP有连接指的是TCP发送数据之间双方需要经过三次握手建立连接;
    所以时间上有延迟;
    2.空间上,需要在端系统中维护连接状态,此连接装入包括接收和发送缓存,拥塞控制参数和序号与确认号的参数。
    3.开销大,时间上三次握手有延迟,所以时间和空间上都比UDP弱了一点

  • UDP 的首部开销小,只有8个字节,比TCP的20个字节的首部要短。

  • UDP 没有拥塞控制,应用层能够更好的控制要发送的数据和发送时间,因此网络出现的拥塞不会使源主机的发送速率降低,只受应用软件生成数据的速率、传输带宽、 源端和终端主机性能的限制。很多的实时应用(如IP电话、实时视频会议等)要去源主机以恒定的速率发送数据,并且允许在网络发生拥塞时丢失一些数据,但却不允许数据有太多的时延。UDP正好符合这种要求。而TCP有拥塞控制参数。

  • UDP提供尽最大努力的交付,不保证可靠交付。所有维护传输可靠性的工作需要用户在应用层来完成。没有TCP的确认机制、重传机制。TCP自己保证可靠性。如果因为网络原因没有传送到对端,UDP也不会给应用层返回错误信息

  • UDP是面向报文的,对应用层交下来的报文,添加首部后直接乡下交付为IP层,既不合并,也不拆分,保留这些报文的边界。对IP层交上来UDP用户数据报,在去除首部后就原封不动地交付给上层应用进程,报文不可分割,是UDP数据报处理的最小单位。
    正是因为这样,UDP显得不够灵活,不能控制读写数据的次数和数量。比如我们要发送100个字节的报文,我们调用一次sendto函数就会发送100字节,对端也需要用recvfrom函数一次性接收100字节,不能使用循环每次获取10个字节,获取十次这样的做法。

  • UDP常用一次性传输比较少量数据的网络应用,如DNS,SNMP等,因为对于这些应用,若是采用TCP,为连接的创建,维护和拆除带来不小的开销。UDP也常用于多媒体应用(如IP电话,实时视频会议,流媒体等)数据的可靠传输对他们而言并不重要,TCP的拥塞控制会使他们有较大的延迟,也是不可容忍的

  • UDP 支持一对一、一对多、多对一和多对多的交互通信,而TCP只能是点对点,一对一。

  • 安全方面的区别
    1.TCP提供可靠的服务,通过TCP连接传送的数据,无差错,保证数据的正确性,不丢失,不重复,且按序到达,有专门的传递保证机制,会确认消息是否收到,并且确认消息收到之后才能继续传送其他消息。
    2.UDP尽最大努力交付,即不保证可靠交付。可能丢包;可能重复;数据顺序不保证,不提供数据包分组、组装和不能对数据包进行排序,数据正确性不保证。UDP协议并不提供数据传送的保证机制。如果在从发送方到接收方的传递过程中出现数据包的丢失,协议本身并不能做出任何检测或提示。应用程序需要负责传输可靠性方面的所有工作。

  • 传输效率的区别
    1.TCP传输效率相对较低。
    2.UDP传输效率高,适用于对高速传输和实时性有较高的通信或广播通信。具有较好的实时性。

  • UDP 段结构比 TCP 的段结构简单,因此网络开销也小。

应用程序可选择自己的重传单元的能力

UDP把数据报发送出去,但并不保证它们能够到达目的地。另外,没有协议机制防止告诉UDP流量对其他网络用户的消极影响。这种可靠性和保护性的缺失需要上层协议来代替UDP完成,但因为UDP的无连接特性,它要比其他传输协议使用更少的开销。另外,广播和组播更多直接使用像UDP这样的无连接传输。最后,应用程序可选择自己的重传单元的能力(因为上层协议可以自主决定要提供多大的可靠性)是一项重要的考虑。

支持UDP的应用

多媒体数据流,不产生任何额外的数据,即使知道有破坏的包也不进行重发。当强调传输性能而不是传输的完整性时,如:音频和多媒体应用,UDP是最好的选择。(如IP电话,实时视频会议,流媒体等)TCP的拥塞控制会使他们有较大的延迟,也是不可容忍的。

在数据传输时间很短,以至于此前的连接过程成为整个流量主体的情况下,UDP也是一个好的选择。

UDP常用一次性传输比较少量数据的网络应用,如DNS,SNMP等,因为对于这些应用,若是采用TCP,为连接的创建,维护和拆除带来不小的开销。

虽然UDP是一个不可靠的协议,但它是分发信息的一个理想协议。例如,在屏幕上报告股票市场、显示航空信息等等。UDP也用在路由信息协议RIP(Routing Information Protocol)中修改路由表。在这些应用场合下,如果有一个消息丢失,在几秒之后另一个新的消息就会替换它。UDP广泛用在多媒体应用中。比如我们聊天用的ICQ和QQ就是使用的UDP协议。

在现场测控领域,面向的是分布化的控制器、监测器等,其应用场合环境比较恶劣,这样就对待传输数据提出了不同的要求,如实时、抗干扰性、安全性等。基于此,现场通信中,若某一应用要将一组数据传送给网络中的另一个节点,可由UDP进程将数据加上报头后传送给IP进程,UDP协议省去了建立连接和拆除连接的过程!取消了重发检验机制,能够达到较高的通信速率。

常用的UDP端口号

常用的UDP端口号有:
53(DNS)
69(TFTP)
161(SNMP)
使用UDP协议包括:
TFTP
SNMP
NFS
DNS
BOOTP

UDP的报文格式

在这里插入图片描述
在TCP/IP协议层次模型中,UDP位于IP层之上。
应用程序访问UDP层然后使用IP层传送数据报。
IP数据包的数据部分即为UDP数据报。
IP层的报头指明了源主机和目的主机地址,而UDP层的报头指明了主机上的源端口和目的端口。
UDP有两个字段:数据字段和首部字段。首部字段很简单,只有8个字节,由4个字段组成,每个字段的长度都是两个字节。具体包括源端口号、目标端口号、数据报长度、校验值。

  1. 源端口:源端口号。在需要对方回信时选用。不需要时可用全0。
  2. 目的端口:目的端口号。这在终点交付报文时必须要使用到。
  3. 长度: UDP用户数据报的长度,其最小值是8(仅有首部),发送一个带0字节数据的UDP数据报是允许的。值得注意的是,UDP长度字段是冗余的;IPV4头部包含了数据报的总长度,同时IPV6头部包含了负载长度。因此,一个UDP/IPV4数据报的长度等于IPV4数据报的总长度减去IPV4头部的长度。一个UDP/IPV6数据报的长度等于包含在IPV6头部中的负载长度(payload length)字段的值减去所有扩展头部(除非使用了超长数据报)的长度。这两种情况下,UDP长度字段应该与从IP层提供的信息计算得到的长度是一致的。
  4. 校验和:检测UDP用户数据报在传输中是否有错。有错就丢弃。
    UDP协议使用报头中的校验值来保证数据的安全。校验值首先在数据发送方通过特殊的算法计算得出,在传递到接收方之后,还需要再重新计算。如果某个数据报在传输过程中被第三方篡改或者由于线路噪音等原因受到损坏,发送和接收方的校验计算值将不会相符,由此UDP协议可以检测是否出错。这与TCP协议是不同的,后者要求必须具有校验值。

许多链路层协议都提供错误检查,包括流行的以太网协议,也许你想知道为什么UDP也要提供检查和校验。其原因是链路层以下的协议在源端和终端之间的某些通道可能不提供错误检测。虽然UDP提供有错误检测,但检测到错误时,UDP不做错误校正,只是简单地把损坏的消息段扔掉,或者给应用程序提供警告信息。

在这里插入图片描述
当运输层从 IP 层收到 UDP 数据报时,根据目的端口,通过相应的端口上交给应用进程。

在这里插入图片描述

如果接收方 UDP发现报文中的目的端口号不正确(即不存在对应于该端口号的应用进程),就丢弃该报文,并由网际控制报文协议 ICMP 发送“端口不可达”差错报文给发送方。
请注意,虽然在 UDP 之间的通信要用到其端口号,但由于 UDP 的通信是无连接的,因此不需要使用套接字(TCP 之间的通信必须要在两个套接字之间建立连接)。

UDP校验和

在这里插入图片描述

UDP校验和覆盖了UDP头部、UDP数据和一个伪头部。
UDP 校验和是一个端到端的传输层校验和,是对包含了IP头部中的源(Source)和目的IP地址(Destination Address)字段的 UDP 伪首部计算得到的。它由初始的发送方计算得到,由最终的目的方校验。它在传输中不会被修改(除非它通过一个NAT)。IPV4 头部中的校验和只覆盖整个头部(即它不覆盖IP分组中的任何数据),它在每个IP跳都要被重新计算(因为IPV4 TTL字段的值在数据报转发时会被路由器减少)。传输协议(如 TCP、UDP)使用校验和来覆盖它们的头部和数据。对于 UDP 来说,校验和是可选的,而其他的则是强制的。当 UDP 在IPV6中使用时,校验和的计算与使用是强制的,因为在IP层没有头部校验和。为了给应用程序提供无差错数据,像UDP这样的传输层协议,在投递数据到接收方应用程序之前,必须计算校验和或者使用其他差错监测机制。

3.1 伪首部
在UDP伪首部中,包含32位源IP地址,32位目的IP地址,8位填充0,8位协议,16位UDP长度。伪首部并非TCP&UDP数据报中实际的有效成分。伪首部是一个虚拟的数据结构,其中的信息是从数据报所在IP分组头的分组头中提取的,既不向下传送也不向上递交,而仅仅是为计算校验和。
伪头部的目的是让UDP层验证数据是否已经到达正确的目的地(即,该IP没有接受地址错误的数据报,也没有给UDP一个本该其他传输协议的数据报),计算UDP校验和时覆盖的字段,包含了伪头部以及UDP头部和负载。

3.2 UDP 校验和计算方法
UDP计算校验和的方法和计算IP数据报首部校验和的方法相似。但不同的是:IP数据报的校验和只检验IP数据报的首部,但UDP的校验和是将首部和数据部分一起都检验。
在发送方,首先是将全零放入检验和字段。再将伪首部以及UDP用户数据报看是由许多16位的字串接起来。若UDP用户数据报的数据部分不是偶数个字节,则要填入一个全零字节(最后一个奇数字节应是16位数的高字节而低字节填0,此字节不发送)。 然后按二进制反码计算出这些16位字的和。 将此和的二进制反码写入校验和字段后,发送此UDP用户数据报。
在接收方,把收到的UDP用户数据报连同伪首部(以及可能的填充全零字节)一起,按二进制反码求这些16位字的和。当无差错时其结果应全为1。否则就表明有差错出现,接收方就丢弃此UDP用户数据报(也可以上交给应用层,但附上出现了差错的警告)。如果校验和字段值为0x0000表示发送方没有计算校验和。

计算UDP校验和的例子
如上图所示,伪首部的第3字段是全零;第4字段是IP首部中的协议字段的值。对于UDP,此协议字段值为17;第5字段是UDP用户数据报的长度。因此,这样的检验和,既检查了UDP用户数据报的源端口和目的端口以及UDP用户数据报的数据部分,又检查了IP数据报的源IP地址和目的地址。注意,UDP数据报的长度在校验和的计算中出现了两次。

计算原理是二进制反码求和运算,具体来说就是:
在这里插入图片描述
如果最高位有进位,就把进位的1取下来与最低位再做一次二进制加法
示例:

在这里插入图片描述

UDP-Lite

有些应用程序可以容忍在发送和接收数据里引入的比特差错。通常,为了避免建立连接的开销或为了使用广播或组播地址,这类应用程序都会选择使用UDP,但是UDP使用的校验和要么覆盖整个负载,要么就干脆没有校验和。一个称为UDP-Lite的协议通过修改传统的UDP协议,提供了部分校验和来解决这个问题。 这些校验和可以只覆盖UDP数据报里的一部分负载。UDP-Lite有它自己的IPv4协议和IPv6下一个头部字段,因此它实际上算是一种独立的传输层协议。UDP-Lite用一个校验和覆盖范围(Checksum Coverage)字段代替了冗余的长度字段来修改传统UDP头部。如下图:

源端口号(2字节) 目的端口号(2字节)
校验和覆盖范围(2字节) 校验和(2字节)

校验和覆盖字段是被校验和覆盖的字节数(从UDP-Lite头部的第1个字节开始)。除了特殊的值以外,最小值是8,因为UDP-Lite头部自身总是要求被校验和覆盖。值0表示整个负载都被校验和覆盖,这就和传统UDP一样了。而对于IPv6超长数据报,因为用于存放校验和覆盖范围字段的空间有限(只有16位),对于这类数据报,被覆盖范围最多可以是64KB或整个数据报(值为0即全覆盖)。

最大UDP数据报长度

理论上,一个IPv4数据报的最大长度是65535字节,这由IPv4头部的16位总长度字段决定。

除去20字节不带选项的IPv4头部和一个8字节的UDP头部,就剩下最大65507字节留个UDP数据报的数据部分。

而对于IPv6,假设没有使用超长数据报,16位负载长度字段可允许655535字节的UDP数据报长度(除去8字节被用于UDP头部后只剩下655527字节)。

虽然理论上可以达到这些数值,但这些大小满额的数据报多数不能被端到端投递。因为可能系统本地协议实现有一些限制(可通过API套接字修改能处理的最大数据报长度),还有可能是应用程序没法处理这么大的数据报。

数据报截断

UDP/IP能发送和接收一个指定大小的数据报并不意味着接收数据报的应用程序能够读取这种大小的数据报。

UDP编程接口允许应用程序指定每次读操作完成时返回的最大字节数。如果接收的数据报超过应用程序的限定值,大多数情况下会发生API截断(truncate),丢弃这个数据报里超过接收应用程序指定字节数的任何超额数据。

但所谓“丢弃”,每种实现的具体操作是不同的,一些系统把这些超额数据放到下一次读操作中,另一些则通知调用者多少数据被截断了(或只报告有数据截断)。

流量和拥塞控制的缺失

大多数UDP服务器是迭代(iterative)服务器,即单个服务器线程(或进程)在单个UDP端口处理所有客户请求。通常一个应用程序使用的每个UDP端口均有一个大小有限的队列与之对应。也就是说来自不同客户机多个请求会被UDP自动排入队列里以一定策略排序(最简单的实现是FCFS,先来先服务),接收到的UDP数据报中排在最前的一个先被传送给应用程序。

然而,这个队列有可能会溢出,使得UDP丢弃进入的数据报。因为UDP不提供流量控制(flow control),也就是说服务器无法让客户机减慢速率。因为UDP是一个无连接协议,自身没有可靠机制,应用程序无法得知什么时候UDP输入队列产生了溢出,超额的数据报仅仅是被丢弃而已。

当网络节点(比如路由器)中发生类似的满队列的情况时,就说网络发生了拥塞(congested)。拥塞会影响所有流量经过拥塞发生地点的网络用户,这与前面提到的UDP输入情况不一样,那里作为端点,只有单个应用程序服务受影响。然而UDP无连接的特性意味着当网络正在拥塞时,不能通知对端降低发送率。

发布了51 篇原创文章 · 获赞 7 · 访问量 5603

猜你喜欢

转载自blog.csdn.net/xxx0028/article/details/104707810