Netty 4 Receive Multicast packets on Linux

风格不统一 提交于 2020-01-13 02:41:31

问题


I have written an app which receives multicast packets sent by a sender (containing audio). I have used Netty 4 and have got the app working on Windows but it will not receive multicast packets when run on Linux (Debian Wheezy (raspi) and Ubuntu 12).

I have created some test code that can send and receive multicast packets, the results are:

Send Windows to Windows works.

Send Linux to Windows works.

Send Windows to Linux, packets are sent but not received.

I run the app as root and have SO_BROADCAST set to true.

What have I missed?

If I use the standard Java MulticastSocket instead of Netty, then the app works, but I would prefer to use Netty as it is easy to use and simplifies to code greatly.

The test code is :

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

}

EDIT:

If found my problem, I should learn to read the docs!!

For Mutlicast you should bind to the WILDCARD Address.

So changing the code to

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

I've modified the full code above with the new changes..

Pete.

来源:https://stackoverflow.com/questions/23445226/netty-4-receive-multicast-packets-on-linux

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!