Netty 4 получает многоадресные пакеты в Linux
Я написал приложение, которое получает многоадресные пакеты, отправленные отправителем (содержащие аудио). Я использовал Netty 4 и получил приложение, работающее под Windows, но оно не будет получать многоадресные пакеты при работе в Linux (Debian Wheezy (raspi) и Ubuntu 12).
Я создал тестовый код, который может отправлять и получать многоадресные пакеты, результаты:
Отправить Windows на Windows работает.
Отправка Linux на Windows работает.
Отправка Windows в Linux, пакеты отправляются, но не принимаются.
Я запускаю приложение от имени пользователя root, и для SO_BROADCAST установлено значение true.
Что я пропустил?
Если я использую стандартную Java MulticastSocket вместо Netty, то приложение работает, но я бы предпочел использовать Netty, поскольку он прост в использовании и значительно упрощает кодирование.
Тестовый код:
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);
}
}
}
РЕДАКТИРОВАТЬ:
Если я нашел мою проблему, я должен научиться читать документы!
Для Mutlicast вы должны связать с адресом WILDCARD.
Так что изменение кода на
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());
}
Я изменил полный код выше с новыми изменениями ..
Пит.