如何ping IP地址

时间:2012-07-16 14:20:29

标签: java ping host

我正在使用这部分代码来ping java中的ip地址,但只有ping localhost成功,对于其他主机,程序说主机无法访问。 我禁用了防火墙,但仍然遇到此问题

public static void main(String[] args) throws UnknownHostException, IOException {
    String ipAddress = "127.0.0.1";
    InetAddress inet = InetAddress.getByName(ipAddress);

    System.out.println("Sending Ping Request to " + ipAddress);
    System.out.println(inet.isReachable(5000) ? "Host is reachable" : "Host is NOT reachable");

    ipAddress = "173.194.32.38";
    inet = InetAddress.getByName(ipAddress);

    System.out.println("Sending Ping Request to " + ipAddress);
    System.out.println(inet.isReachable(5000) ? "Host is reachable" : "Host is NOT reachable");
}

输出结果为:

  

将Ping请求发送到127.0.0.1
  主机可以到达   发送Ping请求到173.194.32.38
  主机无法访问

15 个答案:

答案 0 :(得分:57)

根据{{​​3}}

InetAddress.isReachable()

  

“..典型的实现将使用ICMP ECHO REQUESTs,如果   可以获得特权,否则它将尝试建立TCP   目标主机的端口7(Echo)上的连接..“。

选项#1(ICMP)通常需要管理(root)权限。

答案 1 :(得分:25)

我认为此代码可以帮助您:

public class PingExample {
    public static void main(String[] args){
        try{
            InetAddress address = InetAddress.getByName("192.168.1.103");
            boolean reachable = address.isReachable(10000);

            System.out.println("Is host reachable? " + reachable);
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

答案 2 :(得分:18)

检查您的连接。在我的计算机上,这两个IP打印REACHABLE:

  

将Ping请求发送到127.0.0.1
  主机可以到达   发送Ping请求到173.194.32.38
  主机可以访问

编辑:

您可以尝试修改代码以使用getByAddress()来获取地址:

public static void main(String[] args) throws UnknownHostException, IOException {
    InetAddress inet;

    inet = InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 });
    System.out.println("Sending Ping Request to " + inet);
    System.out.println(inet.isReachable(5000) ? "Host is reachable" : "Host is NOT reachable");

    inet = InetAddress.getByAddress(new byte[] { (byte) 173, (byte) 194, 32, 38 });
    System.out.println("Sending Ping Request to " + inet);
    System.out.println(inet.isReachable(5000) ? "Host is reachable" : "Host is NOT reachable");
}

getByName()方法可能尝试某种反向DNS查找,这可能是您的计算机无法实现的,getByAddress()可能会绕过它。

答案 3 :(得分:13)

你不能简单地使用Java进行ping操作,因为它依赖于ICMP,这在Java中是不可支持的

http://mindprod.com/jgloss/ping.html

使用套接字

希望有所帮助

答案 4 :(得分:12)

它肯定会起作用

import java.io.*;
import java.util.*;

public class JavaPingExampleProgram
{

  public static void main(String args[]) 
  throws IOException
  {
    // create the ping command as a list of strings
    JavaPingExampleProgram ping = new JavaPingExampleProgram();
    List<String> commands = new ArrayList<String>();
    commands.add("ping");
    commands.add("-c");
    commands.add("5");
    commands.add("74.125.236.73");
    ping.doCommand(commands);
  }

  public void doCommand(List<String> command) 
  throws IOException
  {
    String s = null;

    ProcessBuilder pb = new ProcessBuilder(command);
    Process process = pb.start();

    BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
    BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));

    // read the output from the command
    System.out.println("Here is the standard output of the command:\n");
    while ((s = stdInput.readLine()) != null)
    {
      System.out.println(s);
    }

    // read any errors from the attempted command
    System.out.println("Here is the standard error of the command (if any):\n");
    while ((s = stdError.readLine()) != null)
    {
      System.out.println(s);
    }
  }

}

答案 5 :(得分:7)

您可以使用此方法在Windows或其他平台上ping主机:

private static boolean ping(String host) throws IOException, InterruptedException {
    boolean isWindows = System.getProperty("os.name").toLowerCase().contains("win");

    ProcessBuilder processBuilder = new ProcessBuilder("ping", isWindows? "-n" : "-c", "1", host);
    Process proc = processBuilder.start();

    int returnVal = proc.waitFor();
    return returnVal == 0;
}

答案 6 :(得分:4)

简短建议: 不要使用isReachable(),请按照上面的某些答案中的建议,调用系统ping。

详细说明:

  • ping使用ICMP网络协议。要使用ICMP,需要一个“原始套接字”
  • 操作系统不允许标准用户使用原始套接字
  • 以下内容适用于fedora 30 linux,windows系统应类似
  • 如果java以root身份运行,则isReachable()实际上会发送ICMP ping请求
  • 如果java不是以root身份运行,则isReachable()尝试连接到TCP端口7(称为回显端口)。通常不再使用此服务,尝试使用该服务可能会产生不正确的结果
  • 对连接请求的任何回答,同样是拒绝(TCP标志RST)从isReachable()得出'true'
  • 某些防火墙为未明确打开的任何端口发送RST。如果发生这种情况,对于不存在的主机,您将获得isReachable()== true
  • 进一步尝试为Java进程分配必要的功能:
  • setcap cap_net_raw + eip java可执行文件(分配使用原始套接字的权限)
  • 测试:getcap java可执行文件->'cap_net_raw + eip'(已分配功能)
  • 正在运行的Java仍向端口7发送TCP请求
  • 使用getpcaps pid 检查正在运行的Java进程,表明正在运行的Java没有原始套接字功能。显然,我的setcap已被某些安全机制覆盖
  • 随着安全性要求的提高,这可能会变得更加严格,除非s.b.实现了一个特别用于ping的异常(但到目前为止在网上找不到)

答案 7 :(得分:3)


只是对其他人提供的内容的补充,即使它们运行良好,但在某些情况下如果互联网速度很慢或存在某些未知的网络问题,,某些代码将无法正常工作(isReachable())。 但是下面提到的这个代码创建了一个进程,它充当对windows的命令行ping(cmd ping)。它在所有情况下都适用于我,经过了测试和测试。

代码: -

public class JavaPingApp {

public static void runSystemCommand(String command) {

    try {
        Process p = Runtime.getRuntime().exec(command);
        BufferedReader inputStream = new BufferedReader(
                new InputStreamReader(p.getInputStream()));

        String s = "";
        // reading output stream of the command
        while ((s = inputStream.readLine()) != null) {
            System.out.println(s);
        }

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

public static void main(String[] args) {

    String ip = "stackoverflow.com"; //Any IP Address on your network / Web
    runSystemCommand("ping " + ip);
}
}

希望它有所帮助,干杯!!!

答案 8 :(得分:2)

即使它不依赖Windows上的ICMP,该实现也可以与新的Duration API

一起很好地工作
public static Duration ping(String host) {
    Instant startTime = Instant.now();
    try {
        InetAddress address = InetAddress.getByName(host);
        if (address.isReachable(1000)) {
            return Duration.between(startTime, Instant.now());
        }
    } catch (IOException e) {
        // Host not available, nothing to do here
    }
    return Duration.ofDays(1);
}

答案 9 :(得分:1)

在使用oracle-jdk的linux上,OP提交的代码在不是root时使用端口7,在root时使用ICMP。当以文档指定的root身份运行时,它确实会执行真正的ICMP echo请求。

如果您在MS计算机上运行此操作,则可能必须以管理员身份运行应用程序以获取ICMP行为。

答案 10 :(得分:0)

我知道以前的条目已经回答了这个问题,但是对于其他任何人来说,我确实找到了一种不需要使用&#34; ping&#34;在Windows中处理然后擦除输出。

我所做的是使用JNA调用Window的IP帮助程序库来执行ICMP回显

请参阅my own answer to my own similar issue

答案 11 :(得分:0)

InetAddress并不总是返回正确的值。在本地主机的情况下它是成功的,但对于其他主机,这表明主机无法访问。尝试使用ping命令,如下所示。

try {
    String cmd = "cmd /C ping -n 1 " + ip + " | find \"TTL\"";        
    Process myProcess = Runtime.getRuntime().exec(cmd);
    myProcess.waitFor();

    if(myProcess.exitValue() == 0) {

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

答案 12 :(得分:0)

我尝试了几种选择:

  1. Java InetAddress

InetAddress.getByName(ipAddress),Windows上的网络尝试几次后开始运行异常

  1. Java HttpURLConnection

            URL siteURL = new URL(url);
            connection = (HttpURLConnection) siteURL.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(pingTime);
            connection.connect();
    
            code = connection.getResponseCode();
            if (code == 200) {
                code = 200;
            }.
    

这是可靠的,但是有点慢

  1. Windows批处理文件

我最终决定在Windows计算机上创建具有以下内容的批处理文件:ping.exe -n %echoCount% %pingIp% 然后我使用

在我的Java代码中调用了.bat文件
public int pingBat(Network network) {
ProcessBuilder pb = new ProcessBuilder(pingBatLocation);
Map<String, String> env = pb.environment();

env.put(
        "echoCount", noOfPings + "");
env.put(
        "pingIp", pingIp);
File outputFile = new File(outputFileLocation);
File errorFile = new File(errorFileLocation);

pb.redirectOutput(outputFile);

pb.redirectError(errorFile);

Process process;

try {
    process = pb.start();
    process.waitFor();
    String finalOutput = printFile(outputFile);
    if (finalOutput != null && finalOutput.toLowerCase().contains("reply from")) {
        return 200;
    } else {
        return 202;
    }
} catch (IOException e) {
    log.debug(e.getMessage());
    return 203;
} catch (InterruptedException e) {
    log.debug(e.getMessage());
    return 204;
}

}

这被证明是最快,最可靠的方法

答案 13 :(得分:0)

我更喜欢这样:

   /**
     *
     * @param host
     * @return true means ping success,false means ping fail.
     * @throws IOException
     * @throws InterruptedException
     */
    private static boolean ping(String host) throws IOException, InterruptedException {
        boolean isWindows = System.getProperty("os.name").toLowerCase().contains("win");

        ProcessBuilder processBuilder = new ProcessBuilder("ping", isWindows? "-n" : "-c", "1", host);
        Process proc = processBuilder.start();
        return proc.waitFor(200, TimeUnit.MILLISECONDS);
    }

这种方法可以将阻止时间限制为特定时间,例如200毫秒。

它在MacOS,Android和Windows上运行良好,但应在JDK 1.8中使用。

这个想法来自Mohammad Banisaeid,但我无法发表评论。 (您必须拥有50个信誉才能发表评论)

答案 14 :(得分:-2)

这应该有效:

".*Strawberry.*"

}