Domanda

Ho un'applicazione scritta in Java che ha bisogno di trovare tutti gli host raggiungibile in rete.

Io uso InetAddress.isReachable() di fare questo con un timeout di 2000 millisecondi.

I cercare l'indirizzo IP corrente della macchina locale e sulla base di tale tento di raggiungere gli altri indirizzi IP end 1 -. 255 perdendo le macchine locali indirizzo IP

Funziona tutto bene a thread singolo, solo richiede molto tempo come la maggior parte degli indirizzi IP non sono raggiungibili in quanto non esistono in modo da utilizzare il timeout di due secondi.

Per le cose di velocità in su (e provare concorrenza in azione :: Brian Goetz) Ho provato ad utilizzare Future e Callable ecc.

Questo tutto è andato bene pure.

Tuttavia ho immaginato utilizzando ExecutorCompletionService per dare ai miei utenti un'applicazione più reattivo, in modo da poter vedere i risultati come sono venuti disponibili utilizzando

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

L'esecuzione di questo su una macchina singleprocessor con la seguente configurazione fa sì che solo 1 delle quattro host raggiungibili per essere identificato:

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

La modifica a questo su una macchina quad core anche reso sicuro per rilevare tutti gli host raggiungibili:

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

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

Per cambiare il timeout InetAddress.isReachable() a 10 secondi ha fatto l'ultimo ok lavoro config.

Inoltre modificando la configurazione come segue sulla macchina quad core anche fatto funzionare con un secondo timeout 2:

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

mi sto perdendo qualcosa di molto evidente il motivo per cui questo accade?

Cosa si ferma InetAddress.isReachable(2000) di rilevare tutti gli host raggiungibili sulla mia rete?

Perché non si tenta di eseguire chiamate InetAddress.isReachable() più falliscono?

È stato utile?

Soluzione

Così ho scritto un piccolo script di test sul mio Mac e non riesco a farlo fallire - indipendentemente dalle dimensioni della piscina. Ho cambiato il LinkedBlockingQueue ad essere illimitata altrimenti non ho potuto presentare tutti i posti di lavoro. Inoltre, dopo un po 'il metodo isReachable() stava gettando un ConnectException quindi ho dovuto gestire questo specifico. E 'questo il problema con il codice @ user423199?

Ecco il codice:

  

http://pastie.org/2460991

mi chiedo quale sistema operativo è in esecuzione su questo? Alcuni stack IP non possono, come più thread di fare pacchetti ICMP all'interno dello stesso processo. Avrei pensato che tutti i sistemi operativi moderni sarebbe intelligente di questo, ma questo può essere un potenziale problema. Può anche essere un po 'di bug fra il Java JRE e lo stack del sistema operativo.

Spero che questo aiuti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top