21.5 四层网络 --- UDP

IP header足够让一个packet传输到互联网上的任意一个主机,但是我们希望做的更好一些。每一个主机都运行了大量需要使用网络的应用程序,所以我们需要有一种方式能区分一个packet应该传递给目的主机的哪一个应用程序,而IP header明显不包含这种区分方式。有一些其他的协议完成了这里的区分工作,其中一个是TCP,它比较复杂,而另一个是UDP。TCP不仅帮助你将packet发送到了正确的应用程序,同时也包含了序列号等用来检测丢包并重传的功能,这样即使网络出现问题,数据也能完整有序的传输。相比之下,UDP就要简单的多,它以一种“尽力而为”的方式将packet发送到目的主机,除此之外不提供任何其他功能。

UDP header中最关键的两个字段是sport源端口和dport目的端口。

当你的应用程序需要发送或者接受packet,它会使用socket API,这包含了一系列的系统调用。一个进程可以使用socket API来表明应用程序对于特定目的端口的packet感兴趣。当应用程序调用这里的系统调用,操作系统会返回一个文件描述符。每当主机收到了一个目的端口匹配的packet,这个packet会出现在文件描述符中,之后应用程序就可以通过文件描述符读取packet。

这里的端口分为两类,一类是常见的端口,例如53对应的是DNS服务的端口,如果你想向一个DNS server发请求,你可以发送一个UDP packet并且目的端口是53。除此之外,很多常见的服务都占用了特定的端口。除了常见端口,16bit数的剩下部分被用来作为匿名客户端的源端口。比如说,我想向一个DNS server的53端口发送一个packet,目的端口会是53,但是源端口会是一个本地随机选择的端口,这个随机端口会与本地的应用程序的socket关联。所以当DNS server向本地服务器发送一个回复packet,它会将请求中的源端口拷贝到回复packet的目的端口,再将回复packet发送回本地的服务器。本地服务器会使用这个端口来确定应该将packet发送给哪个应用程序。

接下来我们看一下UDP packet的tcpdump输出。首先,我们同样会有一个以太网Header,以及20字节的IP header。IP header中的0x11表明这个packet的IP协议号是17,这样packet的接收主机就知道应该使用UDP软件来处理这个packet。

接下来的8个字节是UDP header。这里的packet是由lab代码生成的packet,所以它并没有包含常见的端口,源端口是0x0700,目的端口是0x6403。第4-5个字节是长度,第6-7个字节是校验和。XV6的UDP软件并没有生成UDP的校验和。

UDP header之后就是UDP的payload。在这个packet中,应用程序发送的是ASCII文本,所以我们可以从右边的ASCII码看到,内容是“a.message.from.xv6”。所以ASCII文本放在了一个UDP packet中,然后又放到了一个IP packet中,然后又放到了一个Ethernet packet中。最后发布到以太网上。

学生提问:当你发送一个packet给一个主机,但是你又不知道它的以太网地址,这个packet是不是会被送到路由器,之后再由路由器来找到以太网地址?

Robert教授:如果你发送packet到一个特定的IP地址,你的主机会先检查packet的目的IP地址来判断目的主机是否与你的主机在同一个局域网中。如果是的话,你的主机会直接使用ARP来将IP地址翻译成以太网地址,再将packet通过以太网送到目的主机。更多的场景是,我们将一个packet发送到互联网上某个主机。这时,你的主机会将packet发送到局域网上的路由器,路由器会检查packet的目的IP地址,并根据路由表选择下一个路由器,将packet转发给这个路由器。这样packet一跳一跳的在路由器之间转发,最终离目的主机越来越近。

学生提问:对于packet的长度有限制吗?

Robert教授:有的。这里有几个不同的限制,每一个底层的网络技术,例如以太网,都有能传输packet的上限。今天我们要讨论的论文基于以太网最大可传输的packet是1500字节。最新的以太网可以支持到9000或者10000字节的最大传输packet。为什么不支持传输无限长度的packet呢?这里有几个原因:

  • 发送无限长度的packet的时间可能要很长,期间线路上会有信号噪音和干扰,所以在发送packet的时候可能会收到损坏的bit位。基本上每一种网络技术都会在packet中带上某种校验和或者纠错码,但是校验和也好,纠错码也好,只能在一定长度的bit位内稳定的检测错误。如果packet长度增加,遗漏错误的可能性就越来越大。所以一个校验和的长度,例如16bit或者32bit,限制了传输packet的最大长度。

  • 另一个限制是,如果发送巨大的packet,传输路径上的路由器和主机需要准备大量的buffer来接收packet。这里的代价又比较高,因为较难管理一个可变长度的buffer,管理一个固定长度的buffer是最方便的。而固定长度的buffer要求packet的最大长度不会太大。

所以,以太网有1500或者9000字节的最大packet限制。除此之外,所有的协议都有长度字段,例如UDP的长度字段是16bit。所以即使以太网支持传输更大的packet,协议本身对于数据长度也有限制。

以上就是UDP的介绍。在lab的最后你们会通过实验提供的代码来向谷歌的DNS server发送一个查询,收到回复之后代码会打印输出。你们需要在设备驱动侧完成以太网数据的处理。

Last updated