【问题标题】:Multicast between applications on the same host同一主机上的应用程序之间的组播
【发布时间】: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


【解决方案1】:

经过一些调试,我意识到如果应用程序本身正在发送多播数据报,我可以从多个应用程序接收多播数据包。事实证明,向多播组发送数据包会以某种方式触发此功能。对我来说这似乎是一个错误。

但是,为了使上述示例按预期工作,我必须向多播通道发送(并丢弃)第一个数据报。我以最简单的方式做到了这一点,将else 块更改为以下内容:

        byte[] buf = new byte[1000];
        DatagramPacket recv = new DatagramPacket(buf, buf.length);
        s.send(new DatagramPacket("A".getBytes(), 1, group, port));
        s.receive(recv);

        System.out.println("RECEIVE MODE");
        s.receive(recv);
        System.out.println(MessageFormat.format("Received: {0}",
                new String(recv.getData()).trim()));

        s.leaveGroup(group);

【讨论】:

  • 这似乎不对。注意你应该使用new String(recv.getData(), 0, recv.getLength())
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-08
  • 2014-02-15
  • 1970-01-01
  • 1970-01-01
  • 2011-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多