同一主机上的应用程序之间的多播

时间:2019-03-09 00:59:13

标签: java network-programming multicast multicastsocket

据我所读,同一主机上的两个应用程序应该有可能能够通过多播发送和接收数据报。我正在尝试使用以下Java代码(这是对MulticastSocket的Javadoc中给出的代码的稍作修改的版本)来实现这一点:

    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作为输入参数,则程序执行得很好,它将发送数据包,然后终止。但是,如果我想接收一个数据包,则该程序会被Receive方法阻止,因为它永远不会获取数据报。我通过在计算机上运行该应用程序的多个实例(包括一个和几个接收者和一个发送者)来测试了这一点。 Non随时会收到任何消息。

另一方面,如果我让应用程序接收它刚刚发送的内容(通过无条件运行该应用程序正在发送的接收方法),则它仅对该应用程序有效。这使我相信JVM实例在该套接字上具有排他绑定,不允许其他人使用它(即使选项getReuseAddress()对于MulticastSockets返回true)。

我正在Windows 10下运行,并且已经验证了使用Wireshark将UDP数据包发送到网络,因此我认为这与该数据包没有传递到两个应用程序有关。

我该怎么做才能允许两个应用程序在同一端口号上通过多播进行通信?

编辑:

总体思路是服务器将数据报发送到所选网络上的所有侦听客户端(因此,在示例中将NIC指定为“ wlan4”的原因),而不管它们在何处执行(例如,在同一主机上)作为服务器)。

1 个答案:

答案 0 :(得分:0)

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

但是,为了按预期方式完成上述示例,我不得不向组播通道发送(并丢弃)第一个数据报。通过将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);