Какой правильный и рабочий способ широковещательной передачи UDP-пакета в Java?

Мне нужно передать UDP-пакет на каждый сетевой интерфейс. Сначала я попробовал транслировать на 255.255.255.255, безрезультатно, и позже я обнаружил, что это "устарело уже около 20 лет". Поэтому я попробовал итерировать каждый сетевой интерфейс, чтобы получить широковещательный адрес интерфейса, а затем отправить UDP-пакет на этот адрес.

Тем не менее, следующий код:

public static Collection getBroadcastAddresses() {
    try {
        Collection result = new LinkedList();
        Enumeration nets = NetworkInterface.getNetworkInterfaces();
        for (NetworkInterface netint : Collections.list(nets))
                for (InterfaceAddress address : netint.getInterfaceAddresses()) {
                    InetAddress broadcastAddress = address.getBroadcast();
                    if (broadcastAddress != null)
                        result.add(broadcastAddress);
                }
        return result;
    } catch (SocketException e) {
        throw new RuntimeException(e);
    }
}

public static void broadcast(int port, DatagramPacket packet,
        DatagramSocket socket, PrintWriter logger) throws IOException {

    packet.setPort(port);

    for (InetAddress address : getBroadcastAddresses()) {
        logger.println("Broadcasting to: "+address);
        packet.setAddress(address);
        socket.send(packet);
    }

}

выводит вот такую фигню:

Broadcasting to: /0.255.255.255
Broadcasting to: /255.255.255.255
Broadcasting to: /255.255.255.255
Broadcasting to: /255.255.255.255
Broadcasting to: /255.255.255.255

что очень раздражает. Я что, должен взять IP-адрес и маску сети для каждого сетевого интерфейса и выполнить побитовые операции, чтобы "построить" правильный широковещательный адрес? Мне кажется, что это похоже на программирование сокетов Unix на C... Есть ли чистый, Java-способ аккуратно доставить несчастный UDP-пакет всем приятелям, которые толпятся в моей сети?

EDIT: поиски в Интернете показали, что на этот раз мой код не сломан. Вместо этого сломалась JVM. Данные, которые вы получаете от InterfaceAddress.getBroadcast(), противоречивы, по крайней мере, под Windows 7. Смотрите, например, this и this: решение, похоже, заключается в установке системного свойства Java, чтобы заставить ее предпочитать IPv4 вместо IPv6, но у меня это не работает. Даже с предложенным обходным решением я получаю разные результаты при каждом разном запуске, и поскольку широковещательный адрес, который я получаю, очевидно, случаен, я подозреваю, что мне предоставляются данные, взятые из областей памяти с неопределенным состоянием. Серьезно, серьезно...

Реализация InterfaceAddress сломана. Теперь у меня большая проблема на моей стороне, потому что я не знаю, как разработать это сетевое приложение. IP multicast широко не поддерживается. Я просто хочу транслировать какую-то фигню на нужный широковещательный UDP-адрес без того, чтобы пользователь писал его в текстовом поле.

7
задан Community 23 May 2017 в 11:55
поделиться