4.3 多接收者

到目前为止,我们的套接字处理的都是两个实体之间的通信,通常是一个服务器和一个客户端。这种一对一的通信方法有时称为单播(unicast)。而对于某些信息,多个接收者都可能对其感兴趣。对于这种情况,我们可以向每个接收者单播一个数据副本,但是这样做效率可能非常低。由于将同样的数据发送了多次,在一个网络连接上单播同一数据的多个副本非常浪费带宽。实际上,如果我们想要以固定频率发送数据,网络连接带宽就已经限制了其所能支持的接收者数量。例如,如果我们的视频服务器以1Mbps的速率发送数据流,而其网络连接速率是3Mbps(良好的连接速率),那么该连接最多只能同时支持3个用户。

幸运的是网络提供了一个更有效地使用带宽的方法。我们可以将复制数据包的工作交给网络来做,而不是由发送者负责。在我们的视频服务器例子中,我们将数据流的单个副本通过服务器连接发送到网络,再由网络在适当的时候将数据复制成多份。使用这种复制模式,无论有多少客户端,服务器都只需要使用其网络连接的1Mbps带宽。

有两种类型的一对多(one-to-many)服务:广播(broadcast)和多播(multicast)。对于广播,(本地)网络中的所有主机都会接收到一份数据副本。对于多播,消息只是发送给一个多播地址(multicast address),网络只是将数据分发给那些表示想要接收发送到该多播地址的数据的主机。总的来说,只有UDP套接字允许广播或多播。

4.3.1 广播

广播UDP数据报文与单播数据报文相似,唯一的区别是其使用的是一个广播地址而不是一个常规的(单播)IP地址。注意,IPv6并没有明确地提供广播地址;然而,这里有一个特殊的全节点(all-nodes)、本地连接范围(link-local-scope)的多播地址,FFO2:1,发送给该地址的消息将多播到一个连接上的所有节点。IPv4的本地广播地址(255.255.255.255)将消息发送到在同一广播网络上的每个主机。本地广播信息决不会被路由器转发。在以太网上的一个主机可以向在同一以太网内的其他主机发送消息,但是该消息不会被路由器转发。IPv4还指定了定向广播地址,允许向指定网络中的所有主机进行广播;然而,由于互联网上的大部分路由器都不转发定向广播消息,我们在此不对其进行介绍。

并不存在可以向网络范围内所有主机发送消息的广播地址。至于为什么没有,请考虑向互联网上每台主机发送广播消息可能产生的影响。在这种地址发送单个数据报文就可能会由路由器产生非常大量的数据包副本,并可能会耗尽所有网络的带宽。误用(恶意的或意外的)该地址的后果会非常严重,因此IP协议的设计者故意没有定义互联网范围的广播机制。

即使如此,本地广播功能还是非常有用的,它通常用于在网络游戏中处于同一本地(广播)网络的玩家之间交换状态信息。在Java中,单播和广播的代码是相同的。要实现具有广播功能的应用程序,我们可以简单地在VoteClientUDP.java中使用广播目的地址。不过这里有个问题,你能发现它吗?提示:广播不能使用连接。像以前那样运行VoteServerUDP.java程序(你还可以同时运行多个接收者)。注意:有些操作系统不允许普通用户进行广播操作,在这种系统上程序将无法正常运行。