8

I need to broadcast an UDP packet on every network interface. At first, I tried broadcasting to 255.255.255.255, with no results, and I later discovered that this "has been deprecated for about 20 years". So I tried iterating on every network interface in order to get the broadcast address of the interface and then send an UDP packet to that address.

Still, the following code:

public static Collection<InetAddress> getBroadcastAddresses() {
    try {
        Collection<InetAddress> result = new LinkedList<InetAddress>();
        Enumeration<NetworkInterface> 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);
    }
    
}

prints this stuff:

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

which is really annoying. Am I supposed to grab the IP address and netmask for every network interface and perform bitwise operations to "build" the correct broadcast address? This seems to me like Unix socket programming in C... Is there a clean, Java way to neatly deliver a miserable UDP packet to all the buddies that crowd my network?

EDIT: searching the web, it turned out that this time my code is not broken. Instead, the JVM is. The data you get from InterfaceAddress.getBroadcast() is inconsistent, at least under Windows 7. See for example this and this: the solution seems to set a Java system property in order to make it prefer IPv4 over IPv6, but this doesn't work for me. Even with the suggested workaround, I get different results on every different run, and since the broadcast address I get is apparently random, I suspect I'm given data taken from undefined state memory locations.

gd1
  • 11,300
  • 7
  • 49
  • 88

1 Answers1

0

You need to get the network IP and mark and use this for broadcast. That the simple part. Then you need to collect all the replies knowing that some servers may not have received the UDP packets and some of the replies could have been lost. You have to allow for the fact that UDP is designed to be unreliable.

I would parse ipconfig /all directly to get the IP and submask. Even ipconfig only has a submask for IPv4

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 1
    Isn't designed to be reliable. Not quite the same thing. – user207421 Nov 24 '11 at 09:34
  • I accept the unreliability of UDP. That's not the point of the question, though... :) I was asking if there's something better than using IP address and netmask. – gd1 Nov 24 '11 at 09:42
  • @EJP, I thought it was designed to drop packets under load. I don't know if this is mentioned in the design however. – Peter Lawrey Nov 24 '11 at 15:00
  • @gd1, In short no. All the alternative I can think of also require you know the interface information and are potentially more complicated. Broadcast UDP is intended for the task you appear to be trying to perform. – Peter Lawrey Nov 24 '11 at 15:02
  • I wouldn't expect 255.255.255.255 to be supported on any network. Broadcast is limited to the subnet of the interface. – Peter Lawrey Nov 24 '11 at 16:15
  • 1
    @PeterLawrey *IP* is designed to drop packets. UDP just inherits that and does nothing about it, unlike TCP. – user207421 Nov 24 '11 at 21:00
  • @gd1 255.255.255.255 doesn't work *because* it was 'deprecated about 20 years ago', as per the quote (from me) that you cited. – user207421 Nov 24 '11 at 21:02