Netty 4和5 - 多播不适合我

时间:2015-04-01 14:06:57

标签: java netty nio multicast

我一直试图让UDP多播与Netty 4.0.26和5.0.0.Alpha2一起使用,但没有任何成功。我修改了this post中的一些代码,这些代码在其编辑的形式中可能有效,但不适合我。附加的代码只是回显“发送1”,“发送2”等,但从未收到相应的数据包。

在表达式localSocketAddr = new InetSocketAddress(localAddr, MCAST_PORT)中,我也试过了端口0,也没有成功。已经尝试了绑定端口和本地地址的各种其他组合。

从我提到的其他帖子中复制了各种套接字选项。

谁能告诉我我做错了什么?这是在Windows 8.1上的Java 8。

非常感谢,

肖恩

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFactory;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramChannel;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.InternetProtocolFamily;
import io.netty.channel.socket.nio.NioDatagramChannel;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;

public class MCast {

    private static final String LOCAL_ADDR = "192.168.0.18";
    private static final String MCAST_GROUP = "239.254.42.96";
    private static final int MCAST_PORT = 9796;

    public static void main(String[] args) throws Exception {
            Thread sender = new Thread(new Sender());
            Thread receiver = new Thread(new Receiver());

            receiver.start();
            sender.start();

            sender.join();
            receiver.join();
    }

    private static class MCastSupport {
            protected InetAddress localAddr;
            protected InetAddress remoteAddr;
            protected InetSocketAddress localSocketAddr;
            protected InetSocketAddress remoteSocketAddr;
            protected DatagramChannel chan;
            protected Bootstrap bootstrap;

            public MCastSupport() {
                    try {
                            localAddr = InetAddress.getByName(LOCAL_ADDR);
                            remoteAddr = InetAddress.getByName(MCAST_GROUP);

                            localSocketAddr = new InetSocketAddress(localAddr, MCAST_PORT);
                            remoteSocketAddr = new InetSocketAddress(remoteAddr, MCAST_PORT);

                            NetworkInterface nif = NetworkInterface.getByInetAddress(localAddr);

                            bootstrap = new Bootstrap()
                                    .group(new NioEventLoopGroup())
                                    .handler(new SimpleChannelInboundHandler<DatagramPacket>() {
                                            @Override
                                            protected void messageReceived(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
                                                    System.out.println("Received: " + msg.content().getInt(0));
                                            }
                                    })
                                    .channelFactory(new ChannelFactory<NioDatagramChannel>() {
                                            @Override
                                            public NioDatagramChannel newChannel() {
                                                    return new NioDatagramChannel(InternetProtocolFamily.IPv4);
                                            }
                                    })
                                    .handler(new SimpleChannelInboundHandler<DatagramPacket>() {
                                            @Override
                                            protected void messageReceived(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
                                                    System.out.println("Received: " + msg.content().getInt(0));
                                            }
                                    })
                            .option(ChannelOption.SO_BROADCAST, true)
                            .option(ChannelOption.SO_REUSEADDR, true)
                            .option(ChannelOption.IP_MULTICAST_LOOP_DISABLED, false)
                            .option(ChannelOption.SO_RCVBUF, 2048)
                            .option(ChannelOption.IP_MULTICAST_TTL, 255)
                            .option(ChannelOption.IP_MULTICAST_IF, nif);

                    chan = (DatagramChannel) bootstrap.bind(localSocketAddr).sync().channel();

                    chan.joinGroup(remoteSocketAddr, nif).sync();

                    } catch (Throwable t) {
                            System.err.println(t);
                            t.printStackTrace(System.err);
                    }
            }
    }

    private static class Sender extends MCastSupport implements Runnable {
            @Override
            public void run() {
                    try {
                            for (int seq = 1; seq <= 5; ++ seq) {
                                    ByteBuf buf = Unpooled.copyInt(seq);
                                    DatagramPacket dgram = new DatagramPacket(buf, remoteSocketAddr, localSocketAddr);
                                    chan.writeAndFlush(dgram);
                                    System.out.println("Send: " + seq);
                                    Thread.sleep(5000);
                            }

                    } catch (Throwable t) {
                            System.err.println(t);
                            t.printStackTrace(System.err);
                    }
            }
    }

    private static class Receiver extends MCastSupport implements Runnable {
            @Override
            public void run() {
                    try {
                            Thread.sleep(5 * 5000);
                    } catch (Throwable t) {
                            System.err.println(t);
                            t.printStackTrace(System.err);
                    }
            }
    }
}

1 个答案:

答案 0 :(得分:2)

我的问题的根源是将ChannelOption.IP_MULTICAST_LOOP_DISABLED设置为false。省略该行(即允许IP_MULTICAST_LOOP_DISABLED默认为true)允许多播按预期工作。坦率地说,这对我来说并没有多大意义,但我没有时间去研究。