The following code opens a UDP socket, sets up multicast, sends a message and starts a read loop. It uses Selector.select() to read with a timeout.
int TIMEOUT = 10000;
String id = "8154@Think420";
try {
NetworkInterface iface = NetworkInterface.getByInetAddress(InetAddress.getByName(address));
try (DatagramChannel channel = DatagramChannel.open(StandardProtocolFamily.INET).setOption(StandardSocketOptions.SO_REUSEADDR, true)) {
channel.socket().bind(new InetSocketAddress(PORT));
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, iface);
channel.configureBlocking(false);
InetAddress group = InetAddress.getByName("225.4.5.6");
MembershipKey key = channel.join(group, iface);
InetSocketAddress mcast = new InetSocketAddress(key.group(), PORT);
channel.send(ByteBuffer.wrap(id.getBytes()), mcast);
Selector selector = Selector.open();
channel.register(selector, SelectionKey.OP_READ);
ByteBuffer buffer = ByteBuffer.allocate(4096);
while (key.isValid()) {
if (selector.select(TIMEOUT) == 0) {
System.err.println("timeout");
continue;
}
buffer.clear();
InetSocketAddress address = (InetSocketAddress) channel.receive(buffer);
buffer.flip();
String message = Charset.forName("ASCII").decode(buffer).toString();
System.err.format("From %s received: %s\n", address.getHostString(), message);
}
} catch(IOException e) {
e.printStackTrace();
}
} catch(UnknownHostException | SocketException e) {
throw new IllegalArgumentException(e);
}
When I run the first instance of the application, it works correctly: receives a single message from itself and then prints "timeout" in a loop.
Here is a sample output:
From 127.0.0.1 received: 8154@Think420
timeout
timeout
timeout
The problem arises when I run another instance. This one works normally, but the first instance starts to report timeouts immediately, flooding its output. The expected behavior here is that when the second instance starts, both first and second receive one message and then report timeouts every ten seconds. What am I doing wrong?