Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当我可以ping IP地址时,为什么InetAddress.isReachable返回false? inetAddressByName=InetAddress.getByName(“173.39.161.140”); System.out.println(按名称); System.out.println(byName.isReachable(1000));_Java_Inetaddress - Fatal编程技术网

Java 当我可以ping IP地址时,为什么InetAddress.isReachable返回false? inetAddressByName=InetAddress.getByName(“173.39.161.140”); System.out.println(按名称); System.out.println(byName.isReachable(1000));

Java 当我可以ping IP地址时,为什么InetAddress.isReachable返回false? inetAddressByName=InetAddress.getByName(“173.39.161.140”); System.out.println(按名称); System.out.println(byName.isReachable(1000));,java,inetaddress,Java,Inetaddress,为什么isReachable返回false?我可以ping IP。在很多情况下,“isReachable”方法不值得我使用。您可以滚动到底部,查看我的备选方案,以便简单地测试您是否在线并能够解析外部主机(即google.com)。。。它通常在*NIX机器上工作 问题 关于这一点有很多议论: 以下是其他类似的问题: 甚至还有一个关于这个问题的bug: 第1部分:问题的可再现示例 注意,在这种情况下,它失败了 //also, this fails for an invalid

为什么
isReachable
返回
false
?我可以ping IP。

在很多情况下,“isReachable”方法不值得我使用。您可以滚动到底部,查看我的备选方案,以便简单地测试您是否在线并能够解析外部主机(即google.com)。。。它通常在*NIX机器上工作

问题

关于这一点有很多议论:

  • 以下是其他类似的问题:

  • 甚至还有一个关于这个问题的bug:

第1部分:问题的可再现示例

注意,在这种情况下,它失败了

       //also, this fails for an invalid address, like "www.sjdosgoogle.com1234sd" 
       InetAddress[] addresses = InetAddress.getAllByName("www.google.com");
      for (InetAddress address : addresses) {
        if (address.isReachable(10000))
        {   
           System.out.println("Connected "+ address);
        }
        else
        {
           System.out.println("Failed "+address);
        }
      }
          //output:*Failed www.google.com/74.125.227.114*
第2部分:黑客解决方案

作为替代方案,您可以执行以下操作:

// in case of Linux change the 'n' to 'c'
    Process p1 = java.lang.Runtime.getRuntime().exec("ping -n 1 www.google.com");
    int returnVal = p1.waitFor();
    boolean reachable = (returnVal==0);
ping的-c选项将允许ping仅尝试访问服务器一次(与我们在终端使用的无限ping相反)

如果可以访问主机,则返回0。否则,您将得到“2”作为返回值

简单得多——但它当然是特定于平台的。 使用这个命令可能会有一些特权警告——但我发现它可以在我的机器上运行


请注意: 1) 此解决方案不符合生产质量。这有点像黑客。如果谷歌关闭,或者您的互联网暂时变慢,或者即使您的权限/系统设置有一些问题,If也可能返回错误否定(即,即使可以访问输入地址,它也可能失败)。
2) isReachable故障是一个悬而未决的问题。同样——有一些在线资源表明,由于JVM试图到达主机的方式,在撰写本文时没有“完美”的方法来完成这项任务——我猜这是一项本质上特定于平台的任务,虽然简单,但JVM尚未充分抽象

如果您只想检查它是否已连接到internet,请使用此方法,如果已连接internet,则返回true,如果您使用您试图通过程序连接的站点的地址,则更可取

     public static boolean isInternetReachable()
    {
        try {
            //make a URL to a known source
            URL url = new URL("http://www.google.com");

            //open a connection to that source
            HttpURLConnection urlConnect = (HttpURLConnection)url.openConnection();

            //trying to retrieve data from the source. If there
            //is no connection, this line will fail
            Object objData = urlConnect.getContent();

        } catch (Exception e) {              
            e.printStackTrace();
            return false;
        }

        return true;
    }

只是明确地提到它,因为其他答案没有。isReachable()的ping部分需要Unix上的root访问权限。正如bestsss在中指出的:

如果你问为什么bash的ping没有,实际上它也需要。这样做ls-l/bin/ping


因为在我的情况下,使用root不是一个选项,所以解决方案是允许我感兴趣的特定服务器访问防火墙中的端口7。

因为您可以ping计算机,所以您的Java进程应该以足够的权限运行以执行检查。可能是因为使用了较低范围的端口。如果您使用sudo/superuser运行java程序,我敢打赌它会工作。

我建议测试internet连接的唯一可靠方法是实际连接并下载文件,或者通过exec()解析操作系统ping调用的输出。ping不能依赖于退出代码,isReachable()是垃圾


不能依赖ping退出代码,因为如果ping命令正确执行,它将返回0。不幸的是,如果ping无法到达目标主机,但从您的家庭ADSL路由器获得“无法访问的目标主机”,则ping将正确执行。这是一种被视为成功命中的回复,因此退出代码=0。必须添加,尽管这是在Windows系统上。未选中*否。

我来这里是为了得到同一个问题的答案,但我对任何答案都不满意,因为我正在寻找一个独立于平台的解决方案。下面是我编写的代码,它与平台无关,但需要关于另一台机器上任何打开端口的信息(我们大部分时间都有)


我不确定2012年最初的问题被问到的时候是什么状态

现在,ping将作为根执行。通过ping可执行文件的授权,您将看到+s标志,以及属于root的进程,这意味着它将作为root运行。在ping所在的位置运行ls-liat,您应该会看到它

因此,如果您以root用户身份运行InetAddress.getByName(“www.google.com”).isReacheable(5000),它应该返回true

您需要对原始套接字进行适当的授权,该套接字由ICMP(ping使用的协议)使用

InetAddress.getByName与ping一样可靠,但您需要对进程拥有适当的权限才能使其正常运行。

或者使用以下方法:

 private boolean isReachable(int nping, int wping, String ipping) throws Exception {

    int nReceived = 0;
    int nLost = 0;

    Runtime runtime = Runtime.getRuntime();
    Process process = runtime.exec("ping -n " + nping + " -w " + wping + " " + ipping);
    Scanner scanner = new Scanner(process.getInputStream());
    process.waitFor();
    ArrayList<String> strings = new ArrayList<>();
    String data = "";
    //
    while (scanner.hasNextLine()) {
        String string = scanner.nextLine();
        data = data + string + "\n";
        strings.add(string);
    }

    if (data.contains("IP address must be specified.")
            || (data.contains("Ping request could not find host " + ipping + ".")
            || data.contains("Please check the name and try again."))) {
        throw new Exception(data);
    } else if (nping > strings.size()) {
        throw new Exception(data);
    }

    int index = 2;

    for (int i = index; i < nping + index; i++) {
        String string = strings.get(i);
        if (string.contains("Destination host unreachable.")) {
            nLost++;
        } else if (string.contains("Request timed out.")) {
            nLost++;
        } else if (string.contains("bytes") && string.contains("time") && string.contains("TTL")) {
            nReceived++;
        } else {
        }
    }

    return nReceived > 0;
}
public static boolean exists(final String host)
{
   try
   {
      InetAddress.getByName(host);
      return true;
   }
   catch (final UnknownHostException exception)
   {
      exception.printStackTrace();
      // Handler
   }
   return false;
}

InetAddress.isReachable
是flappy,有时返回无法访问的地址,我们可以ping这些地址

我尝试了以下方法:

ping-c1
并检查
退出状态

适用于我尝试过的所有情况,
InetAddress.isReachable
不起作用。

检查Internet

public boolean isInternetAvailable() {
        try {
            InetAddress ipAddr = InetAddress.getByName("google.com");
            //You can replace it with your name
            return !ipAddr.equals("");

        } catch (Exception e1) {
            try {
                Process p1 = java.lang.Runtime.getRuntime().exec("/system/bin/ping  -W 1 -c 1 www.google.com");
                int returnVal = 0;
                returnVal = p1.waitFor();
                boolean reachable = (returnVal==0);
                return reachable;
            } catch (Exception e2) {
                e2.printStackTrace();
                return false;
            }
        }
    }
检查网络连接

private boolean isNetworkConnected() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

        return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected();
    }

由于isReachable使用的是TCP协议(通过WireShark),Ping命令使用的是ICMP协议,因此如果要返回true,则需要打开7端口

可能的重复:类似。但是我找不到任何解决问题的线索,所以我在这里重新审视了它。谢谢你的提醒!我会尝试增加超时时间。这是一个很好的问题,没有足够的投票。我发现的唯一一个类似的问题被标记为clojure问题,答案是不确定的。有人能告诉我isReachable()到底做什么吗?即使在本地主机上,它也会返回false…@jayunit100,因为这两种方法都不起作用,
isReachable
我失败了,使用ping我不允许获得icmp?你现在知道怎么处理了吗?@Yuvi如果你使用的是Windows,则标志会有所不同。而不是你想要的-c-n.waitFor()需要10秒才能恢复
public boolean isInternetAvailable() {
        try {
            InetAddress ipAddr = InetAddress.getByName("google.com");
            //You can replace it with your name
            return !ipAddr.equals("");

        } catch (Exception e1) {
            try {
                Process p1 = java.lang.Runtime.getRuntime().exec("/system/bin/ping  -W 1 -c 1 www.google.com");
                int returnVal = 0;
                returnVal = p1.waitFor();
                boolean reachable = (returnVal==0);
                return reachable;
            } catch (Exception e2) {
                e2.printStackTrace();
                return false;
            }
        }
    }
private boolean isNetworkConnected() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

        return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected();
    }