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.