3

我开发客户端-服务器应用程序,实时工作。服务器和客户端通过小消息进行交换,因此我为我的架构选择了 UDP(正如网络中许多文章中所建议的那样)。使用默认的 java 的 DatagramSocket/DatagramPacket 来组织我想要的所有东西对我来说不是问题,但是当我阅读文档时,我看到了“MulticastSocket”的机会。但对我来说完全不清楚:用户端的 MutlicastSocket 将如何知道在哪里连接?(服务器的公共 IP/端口)。真的,正如官方 java教程中所示。MulticastSocket 创建如下:

MulticastSocket socket = new MulticastSocket(4446);
InetAddress group = InetAddress.getByName("203.0.113.0");
socket.joinGroup(group);

并且没有任何关于公共服务器 IP 和端口的规范。什么是“203.0.113.0”?应用程序的音调可能会向网络中的该地址发送一些东西,不是吗?

当我以常规(不是多播)方式创建客户端时,我使用如下内容:

DatagramSocket outputClientSocket = new DatagramSocket();
DatagramPacket outputPacket = new DatagramPacket(new byte[512],512,InetAddress.getByName("94.***.89.***"),9898);
...

其中“94.???.89.???” 是我服务器的公共 IP 地址,而 9898 是我服务器的端口,它会监听它。像那样:

DatagramSocket serverInputSocket = new DatagramSocket(9898);
DatagramPacket inputServerPacket = new DatagramPacket(new byte[512],512);
serverInputSocket.recieve(inputServerPacket);

在收到一些东西后,我可以与客户建立联系,并为他回答一些问题,比如:

DatagramSocket socketForSpecificClient = new DatagramSocket();
InetAddress realClientAddress = inputServerPacket.getAddress();
int realClientPort = inputServerPacket.getPort();
DatagramPacket packetForSpecificClient = new DatagramPacket(new byte[512],512,realClientAddress,realClientPort);
socketForSpecificClient.send(packetForSpecificClient);

即使客户端没有公共 IP,这种方法也很有效。这是为我建立连接的绝对清晰的方式,但我不明白 MulticastSocket 应该用于什么目的?

4

2 回答 2

1

多播在 IPv4 中通常不能跨网段工作。如果您的应用程序应该在 Internet 上运行(而不仅仅是在您控制的 Intranet 中),您不能将您的通信基于多播。

编辑:这里有一些关于这个主题的进一步资源:

关于IP 多播的维基百科:

普通最终用户通常无法使用多播服务

其他 Stackoverflow 问题“互联网上的 UDP 多播?”

通常这是不可能的,因为没有路由多播包。

关于 hardforum.com的讨论“多播是否在 itnernet(原文如此)上工作?”

ISP 过滤多播,您无法通过 Internet 加入多播流。

这些只是谷歌搜索“在互联网上使用多播”时最先点击的几个。

地址范围 203.0.113.0/24 保留用于“文档和示例代码”,因此示例中的地址 203.0.113.0 并不指向真正的端点。

如果您需要一个真实的公共多播地址并通过支持多播的 ISP 进行连接,您必须从IANA 注册中心获取一个。您是对的,任何人都可以向该 IP 地址发送(可能是伪造的)数据,但您对单播地址也有完全相同的问题。如果您在单播地址上提供服务,任何人都可以连接到该地址并向其发送数据。

于 2016-03-24T13:22:54.650 回答
-1

引用Java Network Programming一书中的段落来构建答案:

用户侧的 MutlicastSocket 如何知道连接到哪里?(服务器的公共 IP/端口)?

什么是“203.0.113.0”?应用程序的音调可能会向网络中的该地址发送一些东西,不是吗?

首先,您通常应该使用介于 225.0.0.0 到 238.255.255.255 之间的 IP 地址来创建新的多播组。

当主机想要向多播组发送数据时,它会将数据放入多播数据报中,这只不过是发往多播组的 UDP 数据报。多播数据通过 UDP 发送。

多播地址是称为多播组的一组主机的共享地址。IPv4 多播地址是 CIDR 组 224.0.0.0/4 中的 IP 地址(即,它们的范围从 224.0.0.0 到 239.255.255.255)。

多播组是一组共享多播地址的 Internet 主机。发送到多播地址的任何数据都将转发给该组的所有成员。多播组的成员资格是开放的;主持人可以随时进入或离开群组。组可以是永久的或临时的。IANA 负责根据需要分发永久多播地址。


多播将数据从一台主机发送到许多不同的主机,但不是发送给所有人;数据仅发送给通过加入特定多播组表示有兴趣的客户端。在某种程度上,这就像一个公开会议。人们可以随心所欲地来来去去,在讨论不再感兴趣时离开。在他们到达之前和离开之后,他们根本不需要处理信息:它只是没有到达他们。在 Internet 上,此类“公共会议”最好使用多播套接字来实现,该套接字将数据的副本发送到靠近已声明对数据感兴趣的各方的位置(或一组位置)。

在最好的情况下,数据只有在到达为感兴趣的客户服务的本地网络时才会被复制:数据只通过 Internet 一次。更现实的是,数据的几个相同副本在互联网上传播;但是,通过仔细选择复制流的点,可以最大限度地减少网络上的负载。好消息是程序员和网络管理员不负责选择数据复制的点,甚至不负责发送多个副本。互联网的路由器处理所有这些。


要从远程站点接收多播的数据,首先使用 MulticastSocket() 构造函数创建 MulticastSocket。与其他类型的套接字一样,您需要知道要监听的端口。此代码片段打开一个侦听端口 2300 的 MulticastSocket:

MulticastSocket ms = new MulticastSocket(2300);

接下来,使用 MulticastSocket 的 joinGroup() 方法加入多播组:

InetAddress group = InetAddress.getByName("225.2.2.2");
ms.joinGroup(group);

这会向您和服务器之间的路径中的路由器发出信号,以开始按您的方式发送数据,并告诉本地主机它应该向您传递寻址到多播组的 IP 数据包。加入多播组后,您将像使用 DatagramSocket 一样接收 UDP 数据。

应用程序的音调可能会向网络中的该地址发送一些东西,不是吗?

如果知道提供服务的地址,即使在单播通信的情况下也会面临同样的问题。

于 2016-03-24T13:25:07.843 回答