Pregunta

Tengo una aplicación escrita en Java que tiene que encontrar todos los anfitriones accesible en la red.

Yo uso InetAddress.isReachable() hacer esto con un tiempo de espera de 2000 milisegundos.

buscar la dirección IP de la máquina local actual y sobre la base de que el intento de alcanzar las otras direcciones IP ese fin. 1 - 255 perdiendo las máquinas locales dirección IP

Todo funciona bien solo subproceso, sólo se necesita un largo tiempo ya que la mayoría de las direcciones IP no son accesibles, ya que no existen por lo usan hasta los 2 segundos de tiempo.

Para acelerar las cosas (y probar la concurrencia en acción :: Brian Goetz) He intentado utilizar Future y Callable etc.

Todo esto fue muy bien también.

Sin embargo me pareció usando ExecutorCompletionService dar a mis usuarios de una aplicación más sensible, para que pudieran ver los resultados, ya que llegaron a disposición utilizando

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

La ejecución de este en una máquina singleprocessor con la siguiente configuración hace que sólo 1 de los cuatro hosts alcanzables a ser identificado:

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

Si lo cambia a esto en una máquina de cuatro núcleos también hizo que falle para detectar todos los anfitriones alcanzables:

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

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

Al cambiar el tiempo de espera InetAddress.isReachable() a 10 segundos hizo el último bien el trabajo de configuración.

también cambiando la configuración de la siguiente manera en la máquina de cuatro núcleos también hizo trabajar con un segundo tiempo de espera de 2:

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

Me estoy perdiendo algo muy obvio por qué sucede esto?

¿Qué impide InetAddress.isReachable(2000) de detectar todos los anfitriones accesibles en la red?

¿Por qué no intentar ejecutar varias llamadas InetAddress.isReachable() fallan?

¿Fue útil?

Solución

Así que escribió un pequeño script de prueba en mi Mac y no puedo conseguir que falle - sin importar el tamaño de la piscina. Yo cambio el LinkedBlockingQueue a ser ilimitado lo contrario no podría presentar todos los trabajos. Además, después de un tiempo el método isReachable() estaba lanzando un ConnectException así que tuve que manejar eso específicamente. Es este el problema con el código @ user423199?

Aquí está el código:

http://pastie.org/2460991

Me pregunto qué sistema operativo que está ejecutando en este? Ciertos pilas IP no pueden hacer como múltiples hilos paquetes ICMP dentro del mismo proceso. Yo habría pensado que todos los sistemas operativos modernos serían inteligentes acerca de eso, pero esto puede ser un problema potencial. También puede haber algún error entre el JRE de Java y el conjunto del sistema operativo.

Espero que esto ayude.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top