2009-02-24 4 views
1

Я получаю исключение SocketException при попытке вызвать joinGroup (addr) в MulticastSocket. Это происходит только на машине 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); 

Поскольку это более емким, а также будет гарантировать, что получает сетевой адаптер, который будет на самом деле прием многоадресного сообщения.

Смежные вопросы