Netty 4 recibe paquetes de multidifusión en Linux

He escrito una aplicación que recibe paquetes de multidifusión enviados por un remitente (que contiene audio). He usado Netty 4 y he conseguido que la aplicación funcione en Windows, pero no recibirá paquetes de multidifusión cuando se ejecute en Linux (Debian Wheezy (raspi) y Ubuntu 12).

He creado un código de prueba que puede enviar y recibir paquetes de multidifusión, los resultados son:

Enviar Windows a Windows funciona.

Enviar Linux a Windows funciona.

Envíe Windows a Linux, los paquetes se envían pero no se reciben.

Ejecuto la aplicación como root y tengo SO_BROADCAST establecido en true.

¿Qué me he perdido?

Si uso el Java MulticastSocket estándar en lugar de Netty, entonces la aplicación funciona, pero preferiría usar Netty ya que es fácil de usar y simplifica enormemente el código.

El código de prueba es:

public class TestMulticast {

private int port = 51972;

private Logger log = Logger.getLogger(this.getClass());

private InetAddress remoteInetAddr = null;
private InetSocketAddress remoteInetSocket = null;
private InetAddress localInetAddr = null;
private InetSocketAddress localInetSocket = null;

private DatagramChannel ch = null;
private EventLoopGroup group = new NioEventLoopGroup();
private boolean bSend = false;

public TestMulticast(String localAddress, String remoteAddress, String sPort, boolean bSend) {
    this.bSend = bSend;
    try {
        localInetAddr = InetAddress.getByName(localAddress.trim());
        remoteInetAddr = InetAddress.getByName(remoteAddress.trim());
    } catch (Exception e) {
        log.error("Error creating InetAddresses. Local: " + localAddress + " Remote: " + remoteAddress, e);
    }
    try {
        port = Integer.parseInt(sPort);
    } catch (Exception e) {
        log.error("Error Parsing Port: " + sPort, e);
    }
}

public void run() throws Exception {
    log.debug("Run TestMulticast, Send Packet = " + bSend);
    try {
        localInetSocket = new InetSocketAddress(port);
        remoteInetSocket = new InetSocketAddress(remoteInetAddr, port);

        Bootstrap b = new Bootstrap();
        b.group(group);
        b.channelFactory(new ChannelFactory<Channel>() {
            @Override
            public Channel newChannel() {
                return new NioDatagramChannel(InternetProtocolFamily.IPv4);
            }
        });
        b.option(ChannelOption.SO_BROADCAST, true);
        b.option(ChannelOption.SO_REUSEADDR, true);
        b.option(ChannelOption.IP_MULTICAST_LOOP_DISABLED, false);
        b.option(ChannelOption.SO_RCVBUF, 2048);
        b.option(ChannelOption.IP_MULTICAST_TTL, 255);

        b.handler(new LoggingHandler(LogLevel.DEBUG));
        log.debug("Am I Logged on as ROOT: " + PlatformDependent.isRoot());
        ch = (DatagramChannel) b.bind(localInetSocket).sync().channel();
        log.debug("Result of BIND: " + ch.toString());
        if (remoteInetAddr.isMulticastAddress()) {
            NetworkInterface nic = NetworkInterface.getByInetAddress(localInetAddr);
            ChannelFuture future = ch.joinGroup(remoteInetSocket, nic);
            log.debug("Result of Join: " + future.toString());
        } else {
            log.debug("############NOT A MULTICAST ADDRESS: '" + remoteInetAddr.getHostAddress() + "'");
        }

        if (bSend) {
            group.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    try {
                        Date date = new Date();
                        byte[] bytes = date.toString().getBytes();
                        ByteBuf buffer = Unpooled.copiedBuffer(bytes);
                        DatagramPacket packet = new DatagramPacket(buffer, remoteInetSocket, localInetSocket);
                        ch.writeAndFlush(packet);
                    } catch (Exception e) {
                        log.error("Error Sending DatagramPacket", e);
                    }
                }
            }, 0, 10, TimeUnit.SECONDS);
        }
    } catch (Exception e) {
        log.error(e);
    }
}

public void stop() {
    try {
        if (ch != null) {
            try {
                ch.close();
            } catch (Exception e) {
                log.error("Error Closing Channel", e);
            }
        }
        group.shutdownGracefully();
    } catch (Exception e) {
        log.error("Error ShuutingDown", e);
    }
}

}

EDITAR:

Si encuentro mi problema, ¡debería aprender a leer los documentos!

Para Mutlicast debe vincular a la dirección de WILDCARD.

Entonces cambiando el código a

localInetSocket = new InetSocketAddress(remotePort);

....

ch = (DatagramChannel) b.bind(localInetSocket).sync().channel();

....

if (remoteInetAddr.isMulticastAddress()) {
            NetworkInterface nic = NetworkInterface.getByInetAddress(localInetAddr);
            ChannelFuture future = ch.joinGroup(remoteInetSocket, nic);
            log.debug("Result of Join: " + future.toString());
        }

He modificado el código completo anterior con los nuevos cambios.

Pete

Respuestas a la pregunta(0)

Su respuesta a la pregunta