2009-02-24 89 views
1

尝试在MulticastSocket上调用joinGroup(addr)时,我得到一个SocketException。这只发生在我们设置的Windows机器上,以便在机器启动时自动启动我们的应用程序。MulticastSocket在失败后没有响应

这似乎是引发异常,因为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上无法加入该组会影响没有任何错误地加入的组,并且我该如何解决这个问题?

回答

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); 
    } 

} 
1

我知道这是旧的,但坚实的多播答案似乎很少。

我认为你会用更好:

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

由于这是更简洁,也将确保获得的是将实际接收多播消息的NIC。