我正在 Suse Linux 上使用 Netty 3.6.5.Final 和 JDK7 (Nio.2) 实现一个 UDP 服务器,但我已经碰壁了。该问题专门处理在 Windows 和 MacOS 与 Linux 上绑定到通配符地址 (0.0.0.0) 的差异。
我有一个用于发送数据的多播组和一个用于接收数据的组,它们都绑定到同一个端口。当我尝试在出站组上发布时,我将数据包返回到入站组,这不是 bueno。在 windows/mac 上,这不是问题。一个Linux它得到“混杂”的行为。
在 Linux 上,绑定通配符地址会导致绑定端口上的所有 UDP 流量被传递,而不管组成员身份如何(因此是上面的示例)。对于 MacOS/Windows,您只能从您通过 joinGroup() 订阅的组中获得流量。后者是期望的行为。
Linux 的准解决方案是绑定到您有兴趣从中接收流量的多播组地址。这对于您加入的第一个组(恰好是您绑定的组地址)非常有用。但是,如果您想使用同一订阅者通过 joinGroup() 加入其他组,则不会传递额外的组流量。
我还尝试绑定到默认 NIC 的 IP 地址,并且根本没有传输任何流量。
所以我试过:
if(SystemUtils.IS_OS_MAC_OSX || SystemUtils.IS_OS_WINDOWS) {
socketAddress = new InetSocketAddress(port);
} else {
socketAddress = new InetSocketAddress(getUnixBindAddress(), port);
}
groupChannel = (DatagramChannel)bootstrap.bind(socketAddress);
其中 getUnixBindAddress() 获取默认的 NIC IP 地址。在这种情况下没有流量被传递。
我也试过:
if(SystemUtils.IS_OS_MAC_OSX || SystemUtils.IS_OS_WINDOWS) {
socketAddress = new InetSocketAddress(port);
} else {
socketAddress = new InetSocketAddress(multicastAddress, port);
}
groupChannel = (DatagramChannel)bootstrap.bind(socketAddress);
其中 multicastAddress 是要加入的第一个组的地址。仅传递来自第一个加入组的流量。
我的 joinGroup() 调用如下所示:
ChannelFuture future = groupChannel.joinGroup(new InetSocketAddress(group.getGroupAddress(), group.getPort()), networkInterface);
future.syncUninterruptibly();
和这样的引导代码:
bootstrap = new ConnectionlessBootstrap(new NioDatagramChannelFactory(
Executors.newSingleThreadExecutor(), InternetProtocolFamily.IPv4));
bootstrap.setOption("broadcast", false);
bootstrap.setOption("loopbackModeDisabled", true);
bootstrap.setOption("reuseAddress", true);
bootstrap.setPipelineFactory(this);
如果有人对如何使多个组订阅在 Linux 上为 Netty 工作有任何见解,我将不胜感激。
-布赖恩