如何ping IP地址

Meh*_*hdi 73 java host ping

我正在使用这部分代码来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");
}
Run Code Online (Sandbox Code Playgroud)

输出是:

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

小智 60

InetAddress.isReachable()根据javadoc:

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

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

  • Linux上的`ping`命令是set-uid root;这就是为什么非 root 用户可以使用它,即使它使用 ICMP ECHO_REQUEST。 (9认同)
  • 那么为什么你通常可以在大多数计算机上以非管理员/非root用户身份_在Java_之外? (3认同)

小智 30

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

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Dur*_*dal 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");
}
Run Code Online (Sandbox Code Playgroud)

getByName()方法可能会尝试某种反向DNS查找,这在您的机器上可能是不可能的,getByAddress()可能会绕过它.

  • @vamsi因为IP是以文字形式给出的,所以编译器认为文字是int类型.因为byte的值范围是-128到127,所以该范围之外的值需要显式强制转换(例如,字面值173)."为什么"的根源是javas字节被签名,IP地址通常表示为无符号字节以便于阅读. (3认同)

are*_*tai 15

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

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

请改用套接字

希望能帮助到你

  • 有人可以解释一下这是正确的答案吗? (50认同)
  • 下面有更好的答案 (5认同)

gYa*_*anI 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);
    }
  }

}
Run Code Online (Sandbox Code Playgroud)

  • @Supuhstar 它仅适用于具有 ping 命令的操作系统。基本上它在上面做的是 fork 一个新进程并让它从操作系统运行`ping`命令。 (3认同)

Moh*_*eid 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;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

简短的建议:不要使用 isReachable(),调用系统 ping,如上面一些答案中所建议的那样。

长解释:

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