2013-05-08 54 views
0

我在Suse Linux上使用Netty 3.6.5.Final和JDK7(Nio.2)實現了一個UDP服務器,並且我運行了靠在牆上。該問題專門討論了在Windows和MacOS與Linux上綁定到通配符地址(0.0.0.0)的差異。加入多個組不能在SuSE Linux和JDK7上使用Netty 3.6.5.Final

我有一個用於發送數據的多播組和一個用於接收數據的組,它們都綁定到相同的端口。當我嘗試在出站組上發佈時,我將數據包重新放入入站組,這不是bueno。在Windows/Mac上,這不是問題。一個Linux會得到「混雜」的行爲。

在Linux上,通配符地址上的綁定會導致綁定端口上的所有UDP通信無論組成員身份(因此都是上述示例)都會被髮送。對於MacOS/Windows,您只能通過joinGroup()從您訂閱的羣組獲取流量。後者是期望的行爲。

Linux的準解決方案是綁定到您有興趣接收流量的多播組地址。這對您加入的第一個組非常有用(恰好是您綁定的組地址)。但是,如果您想通過使用同一用戶的joinGroup()加入其他組,則不會傳遞其他組通信。

我也嘗試綁定到默認網卡的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); 

如果任何人有如何進行多組訂閱了Netty的工作對任何見解在Linux上,我會非常感激。

-Brian

回答

0

事實證明,Linux上的默認行爲是複用,這樣當綁定到0.0.0.0所有組播流量收到該端口上所有組的流量。

由於默認行爲,應用程序必須從不需要的組中過濾流量。由於確保只有預期的流量被應用程序接收,這對於安全原因是必要的。

還有一個名爲IP_MULTICAST_ALL的套接字選項,它顯然可以被設置(它在Java中不是標準的,所以我不知道如何),這將迫使堆棧實現所需的非標準行爲。