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