Netty 4 Empfängt Multicast-Pakete unter Linux

Ich habe eine App geschrieben, die von einem Absender gesendete Multicast-Pakete (mit Audio) empfängt. Ich habe Netty 4 verwendet und die App unter Windows zum Laufen gebracht, aber unter Linux (Debian Wheezy (raspi) und Ubuntu 12) werden keine Multicast-Pakete empfangen.

Ich habe einen Testcode erstellt, der Multicast-Pakete senden und empfangen kann. Die Ergebnisse sind:

Senden Sie Windows an Windows funktioniert.

Senden Sie Linux an Windows funktioniert.

Windows an Linux senden, Pakete werden gesendet, aber nicht empfangen.

Ich starte die App als root und habe SO_BROADCAST auf true gesetzt.

Was habe ich vermisst?

Wenn ich anstelle von Netty den Standard-Java-MulticastSocket verwende, funktioniert die App, aber ich würde es vorziehen, Netty zu verwenden, da es einfach zu verwenden und das Codieren erheblich vereinfacht.

Der Testcode lautet:

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

}

BEARBEITEN:

Wenn ich mein Problem gefunden habe, sollte ich lernen, die Dokumentation zu lesen !!

Für Mutlicast sollten Sie sich an die WILDCARD-Adresse binden.

Also ändere den Code auf

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

Ich habe den vollständigen Code oben mit den neuen Änderungen geändert.

Pete.