Вопрос

У меня есть приложение, написанное на Java, которое необходимо найти всех достижимых хостов в сети.

я использую InetAddress.isReachable() сделать это с тайм -аутом 2000 миллисекунд.

Я смотрю IP -адрес текущей локальной машины и исходя из того, что я пытаюсь достичь других IP -адресов, которые заканчиваются 1 - 255, пропускающими IP -адрес локальных машин.

Все работает отлично, один резьба, просто занимает много времени, так как большинство IP -адресов не доступны, поскольку они не существуют, поэтому используйте 2 второго тайм -аута.

Чтобы ускорить ситуацию (и попробуйте параллелизм в действии :: Брайан Гетц) я попытался использовать Future а также Callable и т.п.

Все это тоже прошло хорошо.

Однако мне показалось, используя ExecutorCompletionService Чтобы дать моим пользователям более отзывчивое приложение, чтобы они могли видеть результаты, когда они стали доступными, используя

Future<Reach> reachedFuture = completionService.take();

Запуск этого на одномпроцессорном компьютере со следующей конфигурацией вызывает идентифицировать только 1 из четырех достижимых хостов:

private static final int poolSize = 10;
private static final int maxPoolSize = 10;
private static final long keepAliveTime = 120;

private static final LinkedBlockingQueue<Runnable> queue
        = new LinkedBlockingQueue<Runnable>(20);

private static final ExecutorService executorService
        = new ThreadPoolExecutor(poolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS, queue);

private static final CompletionService<Reach> completionService
        = new ExecutorCompletionService<Reach>(executorService);

Изменение его на четырехъядерную машину также заставило его обнаружить все достижимые хосты:

private static final int poolSize
        = Math.max(2,Runtime.getRuntime().availableProcessors());

private static final int maxPoolSize
        = Math.max(2,Runtime.getRuntime().availableProcessors());

Изменяя InetAddress.isReachable() Тайм -аут до 10 секунд сделал последний конфигуратор.

Также изменяя конфигурацию следующим образом на квад -основной машине, также заставили его работать с 2 -секундным тайм -аутом:

private static final int poolSize = 2;
private static final int maxPoolSize = 2;

Я упускаю что -то очень очевидное, почему это происходит?

Что останавливается InetAddress.isReachable(2000) От обнаружения всех достижимых хостов в моей сети?

Почему попытка запустить несколько InetAddress.isReachable() Вызовы не проходят?

Это было полезно?

Решение

Поэтому я написал небольшой тестовый скрипт на своем Mac и не могу заставить его потерпеть неудачу - независимо от размера бассейна. Я изменил LinkedBlockingQueue Чтобы быть неограниченным, иначе я не мог представить всю работу. Также через некоторое время isReachable() Метод был бросал ConnectException Поэтому мне пришлось справиться с этим конкретно. Это проблема с вашим кодом @user423199?

Вот код:

http://pastie.org/2460991

Мне интересно, на какую ОС вы запускаете это? Некоторые стеки IP могут не любить несколько потоков, выполняющих пакеты ICMP в одном и том же процессе. Я бы подумал, что все современные операционные системы будут разумными в этом, но это может быть потенциальной проблемой. Это также может быть какой -то ошибкой между Java JRE и стеком ОС.

Надеюсь это поможет.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top