Reputation: 2891
I have a multicast socket where I must specify a network interface in order to receive data. However, when I join the group using the network interface Java won't receive it. I have a simple python program that does the exact same thing on the same server and it works fine.
What am I missing in setting up the NetworkInterface for the MulticastSocket in Java?
The java is:
SocketAddress socketAddress = new InetSocketAddress("x.x.x.x", 40000);
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(InetAddress.getByName("z.z.z.z"));
logger.info("Network interface is {} ", networkInterface);
MulticastSocket s = new MulticastSocket();
s.setInterface(InetAddress.getByName("z.z.z.z"));
s.joinGroup(socketAddress,networkInterface);
logger.info(s.getNetworkInterface());
while(true){
try{
logger.info("Waiting for message");
byte[] size = new byte[2];
DatagramPacket recv = new DatagramPacket(size, size.length);
socket.receive(recv);
logger.info("Received size message"); //Never get here
ByteBuffer wrapped = ByteBuffer.wrap(size); // big-endian by default
short messageSize = wrapped.getShort();
byte[] buf = new byte[messageSize-2];
DatagramPacket message = new DatagramPacket(buf, buf.length);
socket.receive(message);
logger.info("Received multicast message");
dataQueue.put(buf);
}catch(Exception e){
logger.error("Failed to receive multicast message ",e);
}
}
The result of this is that I never receive any packets. I have a simple python program that does the same thing and it works perfectly every time.
For reference the python looks like
MCAST_GRP = 'x.x.x.x'
MCAST_PORT = 40000
mcastsock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
mcastsock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
mcastsock.setsockopt(socket.SOL_IP,socket.IP_ADD_MEMBERSHIP,
socket.inet_aton(MCAST_GRP)+socket.inet_aton('z.z.z.z'))
mcastsock.bind((MCAST_GRP,MCAST_PORT))
while True:
print mcastsock.recv(1320)
Upvotes: 1
Views: 2124
Reputation: 2891
Switching this to a MulticastChannel using the nio packages resolved the issue. Not entirely certain it was the cause but the underlying interface was igmp v3 and in some cases it looks like the java multicast code above wouldn't work with that configuration.
More details and a code sample here: https://docs.oracle.com/javase/7/docs/api/java/nio/channels/MulticastChannel.html
// join multicast group on this interface, and also use this
// interface for outgoing multicast datagrams
NetworkInterface ni = NetworkInterface.getByName("hme0");
DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET)
.setOption(StandardSocketOptions.SO_REUSEADDR, true)
.bind(new InetSocketAddress(5000))
.setOption(StandardSocketOptions.IP_MULTICAST_IF, ni);
InetAddress group = InetAddress.getByName("225.4.5.6");
MembershipKey key = dc.join(group, ni);
Upvotes: 1