udp

User Datagram Protocol 用户数据报协议, 一种无连接,不可靠的传输协议。协议号为 17 (IPPROTO_UDP)

有以下特点:

  • 缺乏流量控制

  • 面向无连接
    UDP 是不需要和 TCP一样在发送数据前进行三次握手建立连接的,想发数据就可以开始发送了。并且也只是数据报文的搬运工,不会对数据报文进行任何拆分和拼接操作。
    具体来说就是:

    • 在发送端,应用层将数据传递给传输层的 UDP 协议,UDP 只会给数据增加一个 UDP 头标识下是 UDP 协议,然后就传递给网络层了
    • 在接收端,网络层将数据传递给传输层,UDP 只去除 IP 报文头就传递给应用层,不会任何拼接操作
  • 有单播,多播,广播的功能
    UDP 不止支持一对一的传输方式,同样支持一对多,多对多,多对一的方式,也就是说 UDP 提供了单播,多播,广播的功能

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

  • 不可靠性
    首先不可靠性体现在无连接上,通信都不需要建立连接,想发就发,这样的情况肯定不可靠。
    并且收到什么数据就传递什么数据,并且也不会备份数据,发送数据也不会关心对方是否已经正确接收到数据了。
    再者网络环境时好时坏,但是 UDP 因为没有拥塞控制,一直会以恒定的速度发送数据。即使网络条件不好,也不会对发送速率进行调整。这样实现的弊端就是在网络条件不好的情况下可能会导致丢包,但是优点也很明显,在某些实时性要求高的场景(比如电话会议)就需要使用 UDP 而不是 TCP

  • 头部开销小,传输数据报文时是很高效的

报文格式

报文格式

首部8字节,由4个字段构成。

  • 源端口
    源端口号,需要对方回信时选用,不需要全部置0
  • 目标端口
    目的端口号,在终点交付报文的时候需要用到
  • 长度
    UDP的数据报长度(包含首部和数据),最小值为8(也就是只有首部)
  • 校验和
    检测UDP数据报在传输中是否有错,有错则丢弃
    该字段是可选的,当源主机不想计算校验和,则直接令该字段全为0
    接收方UDP发现收到的报文中的目的端口号不正确(不存在对应端口号的应用进程),就丢弃该报文,并由icmp发送“端口不可达”差错报文给对方。

校验

在计算校验和时,需要在UDP数据报之前增加12字节的伪首部,伪首部不是UDP真正的首部,只是计算校验和时,临时添加在UDP数据报前面,得到一个临时的UDP数据报。伪首部既不向下传送也不向上递交,而仅仅是为了计算校验和。这样的校验和,既检查了UDP数据报,又对IP数据报的源IP地址和目的IP地址进行了检验

UDP伪首部

校验和计算例子

注意:

  • 校验时,若UDP数据报部分的长度不是偶数个字节,则需要填入一个全0字节,但是次字节和伪首部一样,是不发送的
  • 如果UDP校验和校验出UDP数据报是错误的,可以丢弃,也可以交付上层,但是要附上错误报告,告诉上层这是错误的数据报
  • 通过伪首部,不仅可以检查源端口号,目的端口号和UDP用户数据报的数据部分,还可以检查IP数据报的源IP地址和目的地址。这种差错检验的检错能力不强,但是简单,速度快

抓包分析

tcpdump

0x9881 : 源端口号,39041
0x232a : 目标端口号,9002
0x0017 : UDP数据报长度 23 即内容长度为 23 - 8 = 15字节
0xfe2a : 校验和
7468 6973 2069 7320 6120 7465 7374 0a 表示 this is a test\n

udp报文结果

在netinet/udp.h中

struct udphdr
{
  u_int16_t source;  // 源端口
  u_int16_t dest;     // 目标端口
  u_int16_t len;       // 长度
  u_int16_t check;  // 校验和
};
文档更新时间: 2021-02-27 11:18   作者:周国强