MulticastSocket не отвечает после сбоя - PullRequest
1 голос
/ 25 февраля 2009

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

Ответы [ 2 ]

3 голосов
/ 27 февраля 2009

Я так и не выяснил, ПОЧЕМУ сокет не получит сообщения после успешного присоединения к группе. Тем не менее, я нашел способ обойтись.

Я перебираю все сетевые интерфейсы и проверяю, есть ли в списке действительный и работает ли он. Следующее, что я делаю, это попробуйте настроить этот сетевой интерфейс на 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 голос
/ 19 июня 2014

Я знаю, что это старый, но твердые многоадресные ответы кажутся редкими.

Я думаю, вам было бы лучше:

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...