views:

193

answers:

1

I get a SocketException when trying to call joinGroup(addr) on MulticastSocket. This is only happening on a Windows machine that we have setup to auto start our appliction when the machine is booted up.

It seems like the exception is thrown because Windows has not completely finished its startup process and here is the exception.

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)

On startup of our app, if we wait a minute before trying to join the group, everything works fine.

So we decided to put in a retry loop so that it will connect as soon as the network is available which seemed to work. After two failures, the third attempt to join the group works.

The problem is, now the MulticastSocket does not receive any messages from the group, even though it joined up fine.

I am creating a new MulticastSocket after each failure and discarding the old one.

Why would a failure to join the group on one MulticastSocket affect the one that joined without any errors, and how could I possibly work around this?

+1  A: 

I never did find out WHY the socket would not recieve messages after joining the group successfully. I did come up with a work around, however.

I loop through all the network interfaces and make sure there is a valid one in the list and it is up and running. The next thing I do is try setting that network interface on a MulticastSocket. If these tests pass, then I let the socket try to join the group. It seems to work, but I still would like to know more about what is going on behind the scenes.

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

}
Tony Eichelberger