通过在Java

时间:2017-01-24 19:27:03

标签: java android networking ping

我正在尝试通过对每个设备进行ping操作并检查“可达”值来检测连接到我当前所在网络的设备。以下是负责此操作的代码段,循环访问IP,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台笔记本电脑,2台Android设备和1台PC进行测试。其中,它成功地检测到3台笔记本电脑中的2台,这两台Android设备都未能检测到PC。您可以在命令中注意到“-w 1”,我尝试将其设置为100,只是更改是花了很长时间才完成,并且仍然找到了相同的设备。

我也尝试过这种方法:

INetAddress.isReachable(int timeout);

但它变得更糟,因为 - 至少我发现 - 它使用TCP回声,并非所有设备都响应(只有我的Android设备做了)。

此外,ping操作非常慢。我已经将它划分为4个线程,但它仍然可以使用速度提升。

所以,我的最后一个问题是:为什么ping命令无法检测到每个设备&amp;你有没有其他方法可以实现我的目标?

2 个答案:

答案 0 :(得分: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);
            }
        }
    }

答案 1 :(得分:0)

某些计算机由于位于防火墙后面(如@BuMcha所述)或由于他们自己的设置而无法响应ping。如果您可以控制防火墙和单个机器,那么您可以通过在任何地方调整设置来解决这个问题,但这似乎很脆弱。

替代方案可能是发送Address Resolution Protocol (ARP)消息。这些可能会得到广播,但可能会让你以更强大的方式获得你想要的信息。我不确定如何从Java发送这些内容,但另一个问题似乎是针对这一点:Is there a way to send ARP request via Java?