Intereting Posts
очереди производителей / потребителей Установите findbugs NotNull как значение по умолчанию для всех classов под пакетом Что делать без System.out, чтобы печатать на консоли? AppleScript от Java на Mac OS X 10.6? Есть ли способ в logback.xml указать назначение файла журнала через classpath :, без абсолютного пути? Абстрактные методы в Java Без использования UserRecoverableAuthIOException без использования Drive SDK для Android Выключение двойных котировок в строке Как применять размер шрифта при рендеринге HTML-кода на Android или Java Весна 4 с тимелеафом Интернационализация не идентифицирует сообщение из файла свойств ресурса Компиляция не находится на пути сборки Java-проекта – Maven Java 8 – Ссылка на конструктор – тип Select не определяет Select (DataObj), который применим здесь “ Как динамически разрешать параметры сообщений с помощью Hibernate Validator? Как автоматически обнаруживать объекты в JPA 2.0 Infinite While Loop Когда InputMidmatchException попадает в блок try-catch

Каков самый быстрый способ обнаружить недостижимый хост в Java?

Я бы хотел, чтобы самая быстрая и точная функция boolean isReachable(String host, int port) которая проходит следующие тесты JUnit в приведенных ниже условиях. Значения тайм-аута определяются самим тестом JUnit и могут считаться «недоступными».

Обратите внимание: все ответы должны быть независимыми от платформы. Это означает, что InetAddress.isReachable(int timeout) не будет работать, поскольку он использует порт 7 для выполнения ping в Windows (ICMP-пинг является недокументированной функцией в Windows), и этот порт заблокирован в этой настройке.

Настройка локальной сети:

  • thisMachine ( 192.168.0.100 )
  • otherMachine ( 192.168.0.200 )
  • никакая машина не называется noMachine или имеет IP 192.168.0.222 (всегда неansible)
  • обе машины работают с Apache Tomcat на порту 8080 ; все остальные порты недоступны (включая порт 7 )
  • example.com ( 208.77.188.166 ) запускает веб-сервер на порту 80 и доступен только при подключении ЛВС к Интернету

Иногда локальная сеть отключается от Интернета, и в этом случае доступны только локальные компьютеры, вызываемые по IP-адресу (все остальные недоступны, DNS не существует).

Все тесты выполняются на этой thisMachine .

 @Test(timeout=1600) // ~320ms per call (should be possible to do better) public void testLocalhost() { // We can always reach ourselves. assertTrue(isReachable("localhost", 8080)); assertTrue(isReachable("127.0.0.1", 8080)); assertTrue(isReachable("thisMachine", 8080)); // Even if there's no DNS! assertTrue(isReachable("192.168.0.100", 8080)); assertFalse(isReachable("localhost", 80)); // Nothing on that port. } @Test(timeout=5500) // ~1867ms per call (should be able to do better) public void testLAN() { assertTrue(isReachable("192.168.0.200", 8080)); // Always connected to the LAN. assertFalse(isReachable("192.168.0.222", 8080)); // No such a machine. assertFalse(isReachable("noMachine", 8080)); // No such machine. } 

Следующий тест выполняется только тогда, когда LAN отключена от Интернета.

 @Test(timeout=5600) // ~1867ms per call (reasonable?) public void testNoDNS() { assertFalse(isReachable("otherMachine", 8080)); // No DNS. assertFalse(isReachable("example.com", 80)); // No DNS & no Internet. assertFalse(isReachable("208.77.188.166", 80)); // No Internet. } 

Следующий тест выполняется только при подключении ЛВС к Интернету.

 @Test(timeout=5600) // ~1867ms per call (reasonable?) public void testHaveDNS() { assertTrue(isReachable("otherMachine", 8080)); // DNS resolves local names. assertTrue(isReachable("example.com", 80)); // DNS available. assertTrue(isReachable("208.77.188.166", 80)); // Internet available. } 

Во-первых, вам нужно признать, что у вас есть потенциально противоречивые требования; Сокеты IP не детерминированы во времени. Самое быстрое, что вы когда-либо обнаружите недостижимость, – это время, прошедшее с вашего истекшего таймаута. Вы можете быстрее обнаруживать достижимость.

Предполагая, что достижимость / isReachable является вашей реальной целью, вы должны просто использовать простой неблокирующий сокет IO, как показано на симуляторе Java Ping , пример подключается к службе времени, но будет работать одинаково хорошо на 8080.

Если вы хотите проверить, можете ли вы подключиться к веб-серверу, вы также можете создать URL-адрес на основе имени хоста и номера порта и использовать его для создания URLConnection, проверяющего результат (включая исключения) метода connect, который должен сообщить вам, веб-сервер доступен.

Не уверен, насколько это практично.

Как насчет выполнения эквивалента traceroute (tracert on windows), и как только вы получите успех, вы можете продолжить.

В корпоративных сетях я видел, что ICMP (ping) заблокирован админами, НО, как правило, tracert все еще работает. Если вы можете найти быстрый способ сделать то, что делает tracert, это должно сделать трюк?

Удачи!

Мое последнее решение зависит от использования TimedSocket ( исходного кода ) с тайм-аутом 3000 мс при выполнении подключения.

Тайминги:

  • 1406ms: testLocalHost()
  • 5280ms: testLAN()

Не могу даже заставить их работать правильно:

  • testNoDNS()
  • testHaveDNS()

Если вам нужно сделать это с большим количеством хостов за очень короткий промежуток времени, я бы подумал об использовании инструмента, такого как fping вместо shell, для его выполнения и анализа вывода, когда он вернется. fping запускает большое количество параллельных запросов сразу, поэтому вы можете теоретически проверить несколько тысяч хостов за минуту (я думаю, что предел равен 4096?)

Шаг определения скорости для доступности хоста не входит в ваш собственный код, но в netlag. Вы должны дождаться ответа хоста, и это может занять некоторое время. Если ваша программа блокируется в ожидании ответа, это может быть проблемой. Я обошел это, создав каждый хост как объект, каждый со своим собственным поточным методом проверки доступности. В моей собственной ситуации у меня 40 хостов, которые я отслеживаю. Моя основная программа проходит через массив из 40 объектов машины каждые 20 секунд, вызывая соответствующий метод для проверки доступности. Поскольку каждый машинный объект порождает свой собственный stream, чтобы сделать это, все 40 машин опрошены одновременно, и время отклика (до 500 мс) для каждого из них не является проблемой.