Многоадресная рассылка между приложениями на одном хосте - PullRequest
0 голосов
/ 09 марта 2019

Из того, что я прочитал, два приложения на одном хосте должны иметь возможность отправлять и получать дейтаграммы через многоадресную рассылку. Я пытался реализовать это, используя следующий код Java (который является слегка измененной версией того, что дано в Javadoc для 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() возвращает true для MulticastSockets).

Я работаю под Windows 10 и проверил, что пакет UDP отправляется в сеть с помощью Wireshark, поэтому я решил, что это связано с тем, что пакет не доставляется двум приложениям.

Что я могу сделать, чтобы два приложения могли обмениваться данными через многоадресную рассылку с одним и тем же номером порта?

EDIT:

Общая идея заключается в том, чтобы сервер отправлял дейтаграмму всем прослушивающим клиентам в выбранной сети (следовательно, почему в этом примере сетевой адаптер указан как "wlan4"), независимо от того, где они выполняются (например, на одном хосте). как сервер или нет).

1 Ответ

0 голосов
/ 11 марта 2019

После некоторой отладки я понял, что могу получать многоадресные пакеты от нескольких приложений, если само приложение отправляло и получение многоадресных дейтаграмм. Оказывается, отправка пакета в группу многоадресной рассылки как-то запускает эту функцию. Это похоже на ошибку.

Однако, чтобы приведенный выше пример работал должным образом, мне пришлось отправить (и отбросить) первую дейтаграмму на канал многоадресной рассылки. Я сделал это самым простым способом, изменив блок 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);
...