2017-01-24 5 views
0

現在、ネットワークに接続されているデバイスを検出しようとしています。それらのすべてにpingを実行し、「到達可能」値を確認します。ここではそれらをpingを実行し、応答を確認し、IPアドレスを巡回、その責任のコードの一部です:何らかの理由でJavaでpingコマンドを実行してネットワーク上のデバイスを検出します。

 for (int i = 1; i <= 254; i++) { 
      String addr = IPAddress; 
      addr = addr.substring(0, addr.lastIndexOf('.') + 1) + i; 
      InetAddress pingAddr = InetAddress.getByName(addr); 

      //skips the IP of 'this' device 
      if (pingAddr.getHostAddress().equals(IPAddress)) { continue; } 

      try { 

       //ping command 
       Process p1 = java.lang.Runtime.getRuntime().exec("ping -c 1 -w 1 " + addr); 
       boolean reachable = (p1.waitFor() == 0); 
       if (reachable) { 
        //add to list, if reachable 
        addrs.add(pingAddr); 
       } 

      } catch (IOException ex) { 
      } catch (InterruptedException ex) { 
      } 
     } 

、コードのこの作品は、唯一のいくつかのデバイスを検出します。私は3台のノートPC、2台のアンドロイドデバイス、1台のPCをテストしています。このうち、アンドロイドデバイスの3つのラップトップのうち2つが正常に検出され、PCを検出できません。あなたはコマンドで "-w 1"に気付くことができます。私は100に設定しようとしましたが、それは年を取って終了していただけで、同じデバイスが見つかりました。

は私もすでにこの方法で試してみました:

INetAddress.isReachable(int timeout); 

をしかし、それは以降、さらに悪いことになった - 私が見つけた、少なくとも何 - それはないすべてのデバイスが(私だけのAndroidデバイスへの対応TCPエコーを、使用していました)。

また、実際にはpingが遅いです。私はすでにそれを4つのスレッドに分割しましたが、それでもスピードブーストを使用できます。

私の最終的な質問は次のようなものです:なぜpingコマンドがすべてのデバイスを検出できないのですか&私の目標を達成するために考えられる方法はありますか?

答えて

2

多分、PCがファイアウォールの背後にありますか?手動でpingを実行したときに応答しますか?

パフォーマンス向上のために - これを試してみてください。

for (int i = 1; i <= 254; i++) { 
     String addr = ipLocal; 
     addr = addr.substring(0, addr.lastIndexOf('.') + 1) + i; 
     InetAddress pingAddr = InetAddress.getByName(addr); 

     //skips the IP of 'this' device 
     if (pingAddr.getHostAddress().equals(ipLocal)) { continue; } 


     String[] command = {"CMD", "/c", "ping -n 1 -w 1 " + addr}; 
     ProcessBuilder probuilder = new ProcessBuilder(command); 
     Process process = probuilder.start(); 

     InputStream is = process.getInputStream(); 
     InputStreamReader isr = new InputStreamReader(is); 
     BufferedReader br = new BufferedReader(isr); 
     String line; 

     while ((line = br.readLine()) != null) { 
      CharSequence stats = "Packets: Sent = 1, Received = 1"; 
      if(line.contains(stats)){ 
       System.out.println(line); 
       System.out.println(addr); 
       //add to list, if reachable 
       //addrs.add(pingAddr); 
      } 
     } 
    } 
+0

有益な答えをありがとう。ファイアウォールは実際には「問題」でしたが、他のデバイス(同じOS)もファイアウォールの背後にあり、対応しました。 コードを更新していただきありがとうございます。 しかし、ファイアウォールの後ろに、そのようなデバイスを見つける方法はありますか?たとえば、ある企業のネットワークでこのネットワーク上のデバイスを見つけることができるようにするには、このコードが役に立ちます。 そうでない場合は、私はこの質問に合格とマークします。 –

+0

ルータにアクセスすると、接続されているマシンに関する情報を得ることができます。 2番目のアイデアは、nslookupコマンドを試すことです。 – BuMcha

+0

パフォーマンス向上のために私が送ったコードを更新しました。しかし、私はこの例外を受け取ります: I/System.out:java.io.IOException:exec()を実行中にエラーが発生しました。コマンド:[CMD、/ c、ping -n 1 -w 1 192.168.1.245]作業ディレクトリ:null環境:(余りにも長すぎると..) –

0

一部のコンピュータが原因(@BuMchaが述べたように)ファイアウォールの背後にあることに起因するか、独自の設定にpingに応答しません。ファイアウォールや個々のマシンを制御できれば、どこでも設定を調整することでこの問題を回避できる可能性がありますが、それは壊れやすいようです。

代わりにAddress Resolution Protocol (ARP)メッセージを送信することもできます。それらはおそらくブロードキャストを取得しますが、より堅牢な方法で必要な情報を取得できる可能性があります。私はJavaからそれらを送信する方法がわかりませんが、この他の質問はその特定の点に対処しているようです:Is there a way to send ARP request via Java?

関連する問題