Why does InetAddress.isReachable return false, whe

2018-12-31 14:52发布

    InetAddress byName = InetAddress.getByName("173.39.161.140");
    System.out.println(byName);
    System.out.println(byName.isReachable(1000));

Why does isReachable return false? I can ping the IP.

8条回答
牵手、夕阳
2楼-- · 2018-12-31 15:27

Since you can ping the computer, your Java process should run with sufficient privileges to perform the check. Probably due to use of ports in the lower range. If you run your java program with sudo/superuser, I'll bet it works.

查看更多
与风俱净
3楼-- · 2018-12-31 15:32
 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;
}

nping is number of try to ping ip(packets), if you have busy network or systems choose biger nping numbers.
wping is time waiting for pong from ip, you can set it 2000ms
for using this method u can write this:

isReachable(5, 2000, "192.168.7.93");
查看更多
琉璃瓶的回忆
4楼-- · 2018-12-31 15:34

If you only want to check if it is connected to internet use this method , It returns true if internet is connected, Its preferable if you use the address of the site you are trying to connect through the program.

     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;
    }
查看更多
裙下三千臣
5楼-- · 2018-12-31 15:36

Just mentioning it explicitly since the other answers don't. The ping part of isReachable() requires root access on Unix. And as pointed out by bestsss in 4779367:

And if you ask why ping from bash doesn't, actually it does need as well. Do that ls -l /bin/ping.

Since using root was not an option in my case the solution was to allow access to port 7 in the firewall to the specific server I was interested in.

查看更多
旧人旧事旧时光
6楼-- · 2018-12-31 15:37

I would suggest that the ONLY reliable way to test an internet connection is to actually connect AND download a file, OR to parse the output of an OS ping call via exec(). You cannot rely on the exit code for ping and isReachable() is crap.

You cannot rely on a ping exit code as it returns 0 if the ping command executes correctly. Unfortunately, ping executes correctly if it can't reach the target host but gets a "Destination host unreachable" from your home ADSL router. This is kind of a reply that gets treated as a successfull hit, thus exit code = 0. Have to add though that this is on a Windows system. Not checked *nixes.

查看更多
谁念西风独自凉
7楼-- · 2018-12-31 15:42

I came here to get an answer for this same question, but I was unsatisfied by any of the answers because I was looking for a platform independent solution. Here is the code which I wrote and is platform independent, but requires information about any open port on the other machine (which we have most of the time).

private static boolean isReachable(String addr, int openPort, int timeOutMillis) {
    // Any Open port on other machine
    // openPort =  22 - ssh, 80 or 443 - webserver, 25 - mailserver etc.
    try {
        try (Socket soc = new Socket()) {
            soc.connect(new InetSocketAddress(addr, openPort), timeOutMillis);
        }
        return true;
    } catch (IOException ex) {
        return false;
    }
}
查看更多
登录 后发表回答