TCP/IP 教程 | UDP篇

Posted by Aiden on September 1, 2019

UDP是一个简单的面向数据报的运输层协议:进程的每个输出操作都正好产生一个UDP数据报,并组装成一份待发送的IP数据报。

UDP数据报封装成一份IP数据报的格式如图所示。

image.png

UDP不提供可靠性:它把应用程序传给IP层的数据发送出去,但是并不保证它们能到达目的地。由于缺乏可靠性,我们似乎觉得要避免使用UDP而使用一种可靠协议如TCP。

应用程序必须关心IP数据报的长度。如果它超过网络的MTU,那么IP数据报会被分片。

UDP 首部

image.png

字段 说明
端口号 发送进程和接收进程
长度字段 UDP首部和UDP数据的字节长度。这个UDP长度是有冗余的。 IP数据报长度指的是数据报全长,因此UDP数据报长度是全长减去IP首部的长度
检验和 覆盖UDP首部和UDP数据, 检验和算法是把若干个16 bit字相加。 长度不足时最后填充字节0

UDP 校验与差错处理

UDP数据报包含一个12字节长的伪首部,它是为了计算检验和而设置的。伪首部包含IP首部一些字段。其目的是让UDP两次检查数据是否已经正确到达目的地

image.png

如果发送端没有计算检验和而接收端检测到检验和有差错,那么UDP数据报就要被悄悄地丢弃。不产生任何差错报文(当IP层检测到IP首部检验和有差错时也这样做)。

UDP 常见差错

ARP 为空时 UDP 数据包丢弃现象

我们用sock程序来产生一个包含8192字节数据的UDP数据报。预测这将会在以太网上产生6个数据报片。同时也确保在运行该程序前,ARP缓存是清空的,这样,在发送第一个数据报片前必须交换ARP请求和应答。

bsdi % arp -a
bsdi % sock -u -i -nl -w8192 svr4 discard

预计在发送第一个数据报片前会先发送一个ARP请求。IP还会产生5个数据报片,这样就提出了我们必须用tcpdump来回答的两个问题:在接收到ARP回答前,其余数据报片是否已经做好了发送准备?如果是这样,那么在ARP等待应答时,它会如何处理发往给定目的的多个报文?

image.png

在这个输出结果中有一些令人吃惊的结果。首先,在第一个ARP应答返回以前,总共产生了6个ARP请求。我们认为其原因是IP很快地产生了6个数据报片,而每个数据报片都引发了一个ARP请求。

第二,在接收到第一个ARP应答时,只发送最后一个数据报片!看来似乎将前5个数据报片全都丢弃了。实际上,这是ARP的正常操作。在大多数的实现中,在等待一个ARP应答时,只将最后一个报文发送给特定目的主机。

当目的主机不存在时的现象

我们使用 nc 工具向一台不存在的主机发送udp数据包

[hadoop@172.31.27.167:34.199.111.64 ~]$nc -u 172.31.8.40 8080
hello world

但是通过 tcpdump 工具监控数据包, 并没有任何响应报头。 可以看到, 对于不存在的主机发送数据包,并没有任何响应。

当目的主机存在但端口不存在时的现象

当给一个存在的主机一个没有进程监听的端口发送数据

[hadoop@172.31.27.167:34.199.111.64 ~]$nc -u 172.31.8.39 8080
hello world

通过 tcpdump 工具监控

18:17:33.241013 IP ip-172-31-8-39.ec2.internal > ip-172-31-27-167.ec2.internal: ICMP ip-172-31-8-39.ec2.internal udp port webcache unreachable, length 48

发现会收到 icmp 端口不存在错误。


参考内容

document/TCPIP详解卷1协议.pdf at master · Aiden-Dong/document · GitHub