本节书摘来自异步社区《UNIX网络编程 卷1:套接字联网API(第3版)》一书中的第8章,第8.10节,作者:【美】W. Richard Stevens , Bill Fenner , Andrew M. Rudoff著,更多章节内容可以访问云栖社区“异步社区”公众号查看
8.10 UDP程序例子小结
图8-11以圆点的形式给出了在客户发送UDP数据报时必须指定或选择的四个值。
客户必须给sendto调用指定服务器的IP地址和端口号。一般来说,客户的IP地址和端口号都由内核自动选择,尽管我们提到过,客户也可以调用bind指定它们。在客户的这两个值由内核选择的情形下我们也提到过,客户的临时端口是在第一次调用sendto时一次性选定,不能改变;然而客户的IP地址却可以随客户发送的每个UDP数据报而变动(假设客户没有捆绑一个具体的IP地址到其套接字上)。其原因如图8-11所示:如果客户主机是多宿的,客户有可能在两个目的地之间交替选择,其中一个由左边的数据链路外出,另一个由右边的数据链路外出。在这种最坏的情形下,由内核基于外出数据链路选择的客户IP地址将随每个数据报而改变。
如果客户捆绑了一个IP地址到其套接字上,但是内核决定外出数据报必须从另一个数据链路发出,那么将会发生什么?这种情形下,IP数据报将包含一个不同于外出链路IP地址的源IP地址(见习题8.6)。
图8-12给出了同样的四个值,但是是从服务器的角度出发的。
服务器可能想从到达的IP数据报上取得至少四条信息:源IP地址、目的IP地址、源端口号和目的端口号。图8-13给出了从TCP服务器或UDP服务器返回这些信息的函数调用。
TCP服务器总是能便捷地访问已连接套接字的所有这四条信息,而且这四个值在连接的整个生命期内保持不变。然而对于UDP套接字,目的IP地址只能通过为IPv4设置IP_RECVDSTADDR套接字选项(或为IPv6设置IPV6_PKTINFO套接字选项)然后调用recvmsg(而不是recvfrom)取得。由于UDP是无连接的,因此目的IP地址可随发送到服务器的每个数据报而改变。UDP服务器也可接收目的地址为服务器主机的某个广播地址或多播地址的数据报,这些我们将在第20章和第21章中讨论。我们将在22.2节讨论recvmsg函数之后,展示如何确定一个UDP数据报的目的地址。