MulticastSocket не отвечает после сбоя

Я получаю 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)

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

Думаю, вам будет лучше:

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

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

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

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

}