【发布时间】:2019-03-09 00:59:12
【问题描述】:
根据我的阅读,同一主机上的两个应用程序应该可以通过多播发送和接收数据报。我试图使用以下 Java 代码(它是 Javadoc for MulticastSocket 中给出的内容的略微修改版本)来实现这一点:
public static void main(String[] args) throws IOException{
NetworkInterface nic = NetworkInterface.getByName("wlan4");
int port = 6789;
InetAddress group = InetAddress.getByName("228.5.6.7");
MulticastSocket s = new MulticastSocket(port);
s.setNetworkInterface(nic);
s.joinGroup(group);
if(args.length > 0 && args[0].equals("send")){
System.out.println("SEND MODE");
String msg = "Hello";
DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(),
group, port);
s.send(hi);
}else{
byte[] buf = new byte[1000];
DatagramPacket recv = new DatagramPacket(buf, buf.length);
System.out.println("RECEIVE MODE");
s.receive(recv);
System.out.println(MessageFormat.format("Received: {0}",
new String(recv.getData()).trim()));
s.leaveGroup(group);
}
}
如果我运行上面的代码,将send 作为输入参数,程序执行得很好,它发送数据包然后终止。但是,如果我想接收数据包,程序会被接收方法阻止,因为它永远不会收到数据报。我通过在我的机器上运行应用程序的多个实例来测试这一点,包括一个和多个接收器以及一个发送器。 Non 随时收到任何消息。
另一方面,如果我让应用程序接收它刚刚发送的内容(通过无条件地运行接收方法,无论应用程序是否正在发送),它单独适用于该应用程序。这让我相信 JVM 实例在该套接字上有一个独占绑定,不允许其他人使用它(即使选项 getReuseAddress() 为 MulticastSockets 返回 true)。
我在 Windows 10 下运行,并已验证 UDP 数据包是使用 Wireshark 发送到网络的,所以我认为这与数据包未传递到两个应用程序有关。
如何才能让两个应用程序在同一个端口号上通过多播进行通信?
编辑:
总体思路是服务器向所选网络上的所有侦听客户端发送数据报(因此在示例中将 NIC 指定为“wlan4”),而不管它们在何处执行(例如,在同一主机上)是否作为服务器)。
【问题讨论】:
-
当所有必需的通信都在本地主机内时,为什么要强制多播套接字使用
wlan4? -
好点,我意识到我可能没有解释我的整体意图。这个想法是让发送者发送一个数据报以被网络上的所有客户端捕获,而不管客户端是否与服务器位于同一主机上。
-
您是否禁用了多播环回?在我看来,您只收到环回,并且您的
joinGroup()根本没有在您的本地主机之外生效。尝试删除setNetworkInterface()行。 -
发送者需要数据包的源端口与目标端口(在您的示例中为 6789)相同是否有明确的原因?如果没有,让发送者从任意 DatagramSocket 发送数据包会容易得多,只是为了这个目的而打开。请注意,在发送数据报时,发送方并不关心目标是 mcast 还是单播地址,即您不需要 MulticastSocket 来发送 mcast 消息。
标签: java network-programming multicast multicastsocket