3

尝试在 MulticastSocket 上调用 joinGroup(addr) 时出现 SocketException。这只发生在我们设置为在机器启动时自动启动我们的应用程序的 Windows 机器上。

似乎抛出异常是因为 Windows 尚未完全完成其启动过程,这里是异常。

java.net.SocketException: error setting options

    at java.net.PlainDatagramSocketImpl.join(Native Method)

    at java.net.PlainDatagramSocketImpl.join(Unknown Source)

    at java.net.MulticastSocket.joinGroup(Unknown Source)

在我们的应用程序启动时,如果我们在尝试加入群组之前等待一分钟,一切正常。

所以我们决定放入一个重试循环,以便它在网络可用时立即连接,这似乎工作。两次失败后,第三次尝试加入该组成功。

问题是,现在 MulticastSocket 没有收到来自组的任何消息,即使它加入得很好。

每次失败后我都会创建一个新的 MulticastSocket 并丢弃旧的。

为什么在一个 MulticastSocket 上加入组失败会影响没有任何错误加入的组,我怎么可能解决这个问题?

4

2 回答 2

3

我从来没有发现为什么套接字在成功加入组后不会收到消息。然而,我确实想出了一个解决方法。

我遍历所有网络接口并确保列表中有一个有效的接口并且它已启动并正在运行。我要做的下一件事是尝试在 MulticastSocket 上设置该网络接口。如果这些测试通过,那么我让套接字尝试加入组。它似乎有效,但我仍然想了解更多关于幕后发生的事情。

private void validateNetworkInterfaces() throws IOException {

    Enumeration nis = NetworkInterface.getNetworkInterfaces();
    List<NetworkInterface> nics = new ArrayList<NetworkInterface>();
    while (nis.hasMoreElements()) {
        NetworkInterface ni = (NetworkInterface) nis.nextElement();

        logger.debug("nic name: " + ni.getDisplayName());
        logger.debug("nic isLoopback(): " + ni.isLoopback());
        logger.debug("nic isPointToPoint(): " + ni.isPointToPoint());
        logger.debug("nic isVirtual(): " + ni.isVirtual());
        logger.debug("nic isUp(): " + ni.isUp());
        logger.debug("nic supportsMulticast(): " + ni.supportsMulticast());

        if (!ni.isLoopback() && !ni.isPointToPoint() && !ni.isVirtual() && ni.isUp() && ni.supportsMulticast()) {
            logger.debug("adding nic: " + ni.getDisplayName());
            nics.add(ni);               
        }               

    }

    //check to make sure at least one network interface was found that supports multicast.
    if (nics.size() == 0) throw new SocketException("No network interfaces were found that support multicast.");

    //make sure the network interface can be set on a multicast socket
    for (NetworkInterface nic : nics) {
        logger.debug("attempting to set network interface on nic: " + nic.getDisplayName());
        MulticastSocket ms1 = new MulticastSocket(45599);
        ms1.setNetworkInterface(nic);
    }

}
于 2009-02-26T21:50:02.993 回答
1

我知道这是旧的,但可靠的多播答案似乎很少见。

我认为你会更好:

final InetAddress localHost = InetAddress.getLocalHost();
final NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);

因为这更简洁,并且还可以确保获得一个将实际接收多播消息的 NIC。

于 2014-06-19T14:01:39.227 回答