问题描述
在尝试让一个简单的 UDP 多播接收器工作后,我感到很困惑.在我自己的代码没有按预期工作后,我尝试了 vertx 文档中发布的确切示例:
i'm puzzeled after a few attempts to get a simple UDP multicast receiver working.After my own code did not work as expected i tried out the exact example posted in the vertx documentation:
DatagramSocket socket = vertx.createDatagramSocket(new DatagramSocketOptions());
socket.listen(1234, "0.0.0.0", asyncResult -> {
if (asyncResult.succeeded()) {
socket.handler(packet -> {
// Do something with the packet
});
// join the multicast group
socket.listenMulticastGroup("230.0.0.1", asyncResult2 -> {
System.out.println("Listen succeeded? " + asyncResult2.succeeded());
});
} else {
System.out.println("Listen failed" + asyncResult.cause());
}
});
执行后,我得到以下异常:
After executing, i got the following exception:
java.lang.NullPointerException: networkInterface
at io.netty.channel.socket.nio.NioDatagramChannel.joinGroup(NioDatagramChannel.java:409)
at io.netty.channel.socket.nio.NioDatagramChannel.joinGroup(NioDatagramChannel.java:368)
at io.netty.channel.socket.nio.NioDatagramChannel.joinGroup(NioDatagramChannel.java:362)
at io.vertx.core.datagram.impl.DatagramSocketImpl.listenMulticastGroup(DatagramSocketImpl.java:90)
当提供正确的网络接口 IP 地址(例如 192.168.178.52)而不是 0.0.0.0 时,我可以让它工作.然而,这意味着遍历所有网络接口并为每个接口添加一个套接字.
I can get it to work when providing the right IP address of the network interface (e.g. 192.168.178.52) instead of 0.0.0.0. However, this means iterating over all network interfaces and adding a socket per interface.
有什么想法吗?谢谢!
推荐答案
UDP 多播监听极其容易出错,尤其是在虚拟机中.
UDP multicast listening is incredibly error prone, especially in virtual machines.
这是来自我的生产代码.首先,要获得一个有效的接口:
This is from my production code. First, to get a valid interface:
static NetworkInterface mainInterface() throws SocketException {
final ArrayList<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
final NetworkInterface networkInterface = interfaces.stream().filter(ni -> {
boolean isLoopback = false;
boolean supportsMulticast = false;
boolean isVirtualbox = false;
try {
isLoopback = ni.isLoopback();
supportsMulticast = ni.supportsMulticast();
isVirtualbox = ni.getDisplayName().contains("VirtualBox") || ni.getDisplayName().contains("Host-Only");
} catch (IOException loopbackTestFailure) {
}
final boolean hasIPv4 = ni.getInterfaceAddresses().stream().anyMatch(ia -> ia.getAddress() instanceof Inet4Address);
return supportsMulticast && !isLoopback && !ni.isVirtual() && hasIPv4 && !isVirtualbox;
}).sorted(Comparator.comparing(NetworkInterface::getName)).findFirst().orElse(null);
return networkInterface;
}
然后,最防弹的数据报套接字创建:
Then, the most bullet-proof datagram socket creation:
String multicastAddress = "230.0.0.1";
NetworkInterface networkInterface = mainInterface();
Future isListening = Future.future();
vertx.createDatagramSocket(new DatagramSocketOptions()
.setReuseAddress(true)
.setReusePort(true))
.listen(6112, "0.0.0.0", next -> {
next.result().listenMulticastGroup(multicastAddress, networkInterface.getName(), null, listener -> {
final DatagramSocket socket = listener.result();
socket.handler(packet -> {
// Your handler here
});
isListening.complete();
});
});
请注意我为 VirtualBox 选择的高于 1024 的端口、重用标志和特殊外壳.
Observe my choice of a higher-than-1024 port, the reuse flags, and the special casing for VirtualBox.
这篇关于尝试接收 UDP 多播时出现空指针异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!