简体   繁体   中英

Java multicast socket not receiving on specific network interface

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)

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM