UDP协议

814 阅读6分钟

UDP协议概述

UDP(User Datagram Protocol),用户数据报协议,是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。UDP报文没有可靠性保证、顺序保证和流量控制字段等,可靠性较差。但是正因为UDP协议的控制选项较少,在数据传输过程中延迟小、数据传输效率高,适合对可靠性要求不高的应用程序。 UDP在IP报文中的位置如下图所示:

这里写图片描述
可以看到,UDP其实就是在IP报文中添加了端口信息,使数据到达主机后送达至相应端口的应用程序。下面是通过wireshark抓的一个UDP数据包:
在这里插入图片描述

UDP报头

UDP报头由4个域组成,其中每个域各占用2个字节,如下图所示:

这里写图片描述

可以看到头部十分简单,只有4个字段:

  • 源端口号: 表示发送方的端口,是可选的,如果发送者不要求对方回复的话,它可以被置为0;
  • 目的端口号: 接收方端口号;
  • 数据报长度: 是指包括报头和数据部分在内的总字节数。因为报头的长度是固定的,所以该域主要被用来计算可变长度的数据部分(又称为数据负载)。数据报的最大长度根据操作环境的不同而各异。从理论上说,包含报头在内的数据报的最大长度为 2^{16}-1= 65535 字节。
  • 校验和: UDP协议使用报头中的校验值来保证数据的安全。该校验和是可选的,默认是进行校验,但不是必须的,如果不想计算校验和,则置0即可,接收方发现是0就不会再进行校验。

UDP与TCP的主要不同

UDP与TCP的不同,通过对头部的对比就可以发现,UDP不建立连接,报头很短,UDP没有流量控制,没有状态信息,区别与TCP的流传输UDP面向报文传输,对此总结如下几点不同:

  • 不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。

  • UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。

  • 没有流控,吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。

  • 没有状态信息,UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。

  • UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。

编写UDP程序时应当注意的问题:UDP数据报重组

与TCP的通信机制不同,UDP是基于事务的,应用程序要发送数据时,它仅是发送数据而已。很多使用UDP的应用程序发送的数据量很小,用一个数据段就够了。但是也有一些应用程序需要发送大量数据,因此需要用多个数据段。这时要注意以下两点:

  • 将多个数据报发送到目的主机时,它们可能使用了不同的路径,到达顺序也可能跟发送时的顺序不同。与TCP不同,UDP不跟踪序列号。UDP不会对数据报重组,因此也不会将数据恢复到传输时的顺序。
  • 因此,UDP仅仅是将接收到的数据按照先来后到的顺序转发到应用程序。如果数据的顺序对应用程序很重要,那么应用程序只能自己标志数据的正确顺序,并决定如何处理这些数据。

对UDP一次发送多少bytes好?问题的思考

在进行UDP编程的时候,我们最容易想到的问题就是,一次发送多少bytes好?当然,这个没有唯一答案。需求不同,环境不同,这里只是对其进行相关的思考。最主要的考虑就是尽可能避免IP层分片。

首先,我们知道TCP/IP通常被认为是一个四层协议系统,包括链路层、网络层、传输层、应用层。UDP属于传输层,下面我们由下至上一步一步来看: 以太网(Ethernet)数据帧的长度必须在46-1500字节之间,这是由以太网的物理特性决定的。这个1500字节被称为链路层的MTU(最大传输单元)。 但这并不是指链路层的长度被限制在1500字节,其实这个MTU指的是链路层的数据区并不包括链路层的首部和尾部的18个字节。所以事实上这个1500字节就是网络层IP数据报的长度限制。因为IP数据报的首部为20字节,所以IP数据报的数据区长度最大为1480字节。而这个1480字节就是用来放TCP传来的TCP报文段或UDP传来的UDP数据报的。又因为UDP数据报的首部8字节,所以UDP数据报的数据区最大长度为1472字节。这个1472字节就是我们可以使用的字节数。

当我们发送的UDP数据大于1472的时候会怎样呢? 这也就是说IP数据报大于1500字节,大于MTU。这个时候发送方IP层就需要分片(fragmentation)。把数据报分成若干片,使每一片都小于MTU。而接收方IP层则需要进行数据报的重组。这样就会多做许多事情,而更严重的是,由于UDP的特性,当某一片数据传送中丢失时,无法重组数据报,将导致丢弃整个UDP数据报。因此,在普通的局域网环境下,建议将UDP的数据控制在1472字节以下为好。

进行Internet编程时则不同,因为Internet上的路由器可能会将MTU设为不同的值。如果我们假定MTU为1500来发送数据的,而途经的某个网络的MTU值小于1500字节,那么系统将会使用一系列的机制来调整MTU值,使数据报能够顺利到达目的地,这样就会做许多不必要的操作。鉴于Internet上的标准MTU值为576字节,所以建议在进行Internet的UDP编程时,最好将UDP的数据长度控件在548字节(576-8-20)以内。

关注微信公众号,定期推送TCP/IP、后端开发、区块链、Rust等技术分享文章!