| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java: Работа с сетью > Проблемы проверки доступности узла с использованием InetAddress.isReachable() |
| Автор: LSD 8.2.2008, 19:55 |
| Предыстория: на форуме периодически возникают вопросы как проверить тот или иной хост на доступность. По попросту говоря попинговать его. До JDK 1.5 стандартной возможности не было в принципе. Начиная с JDK 1.5 у InetAddress появился метод isReachable(), который должен проверять хост на доступность. Но при использовании этого метода, периодически возникают проблемы. Если у вас установлен файервол в режиме обучения, то при вызове метода InetAddress.isReachable() вы увидите что Java пытается установить TCP соединение по 7 порту с искомым узлом. Если посмотреть http://www.iana.org/assignments/port-numbers, то видно что порт 7 (как TCP, так UDP) предназначен для echo request. А вот дальше и начинается самое интересное, дело в том, что подавляющие большинство серверов принимают echo request только по протоколу UDP, а по протоколу TCP - нет. Почему это сделано я точно не знаю, но http://bordet.blogspot.com/2006/07/icmp-and-inetaddressisreachable.html прочитал такую версию: в WinAPI нет функции которая бы позволяла бы выполнить ping, поэтому чтобы не завязываться на всякие нестандартные вещи просто используется только проверка по TCP порту (хотя та же icmp.dll присутствует и что мешает ей воспользоваться - непонятно). Под Linux ситуация следующая: такая функция есть, но её использование требует прав root, т.к. большинство программ запускается не от root, то попытка вызова ведёт к ошибке. И далее снова идёт попытка использования TCP. Вариантов борьбы с этой проблемой не так много: 1. Написать свою native функцию которая будет или вызывать icmp.dll или сама сформирует http://www.networksorcery.com/enp/protocol/icmp/msg8.htm ICMP пакета и отправит его. 2. Вызывать системные утилиты ping и анализировать результат. 3. Попытаться соединиться по другому порту, который заведомо открыт. Например если мы знаем, что на хосте работает веб сервер, то можно попытаться соединиться по 80 порту. |