找了很多关于netty使用多播的文章和code, 有的只是简单的代码并未对应用做出说明,而且这其中碰到不少的问题。
开始使用的代码段来自于netty的example。但是加入组播后并没有监听到组播的udp消息,用wireshark是可以抓到设备发送的udp组播信息的。我发现不用netty的情况下和使用别的语言进行编程的时候度需要将joinGroup绑定的0.0.0.0这个NetworkInterface上,并未对着个部分做出过说明。
过程中在加入组播是会报ipv6 无法加入ipv4的组播;这个错误需要利用ChannelFactory来规避掉。
再到本地windows运行编译没有出现问题,打包放到linux系统上运行时会无法接受到对应组播地址的消息。使用netstat -ng对比window上的netstat时,发现linux系统没有加入到这个组播地址中,使用命令加入组播后就能正常接受信息。
下面的代码供参考,netty以及udp多播的中文资料太少了,连问题也很少,很多都是复制粘贴的,我的大部分问题都是搜索英文答案得以解决的,希望有更多的人能分享知识在中文社区。
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.InternetProtocolFamily;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.util.NetUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.net.*;
import java.util.Enumeration;
@Component
@Slf4j
public class MulticastServer extends Thread {
@SneakyThrows
@PostConstruct
public void run() {
EventLoopGroup group = new NioEventLoopGroup();
try {
// NetworkInterface ni = NetworkInterface.getByName("eth0");
NetworkInterface ni = NetUtil.LOOPBACK_IF;
Enumeration networkInterface = NetworkInterface.getNetworkInterfaces();
Enumeration addresses = ni.getInetAddresses();
log.info("address:"+addresses);
MulticastSocket multicastSocket = new MulticastSocket();
NetworkInterface ifc = multicastSocket.getNetworkInterface();
Bootstrap b = new Bootstrap();
b.group(group)
.channelFactory((ChannelFactory) () -> new NioDatagramChannel(InternetProtocolFamily.IPv4))
.localAddress(xxx)
.option(ChannelOption.IP_MULTICAST_IF, ifc)
.option(ChannelOption.SO_RCVBUF,1024*2048)
.option(ChannelOption.SO_REUSEADDR, true)
.handler(new ChannelInitializer() {
@Override
public void initChannel(NioDatagramChannel ch) throws Exception {
ch.pipeline().addLast(new ServerMulticastHandler());
}
});
//
NioDatagramChannel ch = (NioDatagramChannel) b.bind(21078).sync().channel();
InetSocketAddress groupAddress = new InetSocketAddress("xxx.xxx.x.x",xxx);
InetAddress addr = InetAddress.getByName("xxx.xxx.xxx.xxx");
//以上的地址为多播组
InetSocketAddress ga2 = new InetSocketAddress("0.0.0.0",21078);
// log.info("addr:"+ groupAddress);
// ss.joinGroup(groupAddress,ifc);
ch.joinGroup(groupAddress,ifc).sync();
log.info("multicast start"+ch);
//
// log.info("multicast start");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
// InetSocketAddress groupAddress = new InetSocketAddress("234.128.1.2", 21078);
System.setProperty("java.net.preferIPv4Stack" , "true");
new MulticastServer().run();
}
}



