如何从Windows做一个真正的Java ping?

2022-09-01 14:18:43

我在网络上有一个设备,我正在尝试通过我的Java程序ping。通过我的Windows命令提示符,我可以很好地ping设备地址,并对地址进行跟踪。

在线上,我已经看到,为了通过Java执行ping,您必须执行以下操作:

InetAddress.getByName(address).isReachable(timeout);

但是,当我在设备地址上使用此代码时,它总是在我的程序中返回false。我使用的是正确的IPv4地址,具有良好的超时值。另外,如果我使用本地主机地址,它工作正常。

为什么我可以通过cmd ping设备,但不能通过我的程序ping设备?我在很多地方都听说过这不是一个真正的ping。

有没有更好的方法来模拟Java中的ping?

谢谢


答案 1

isReachable()如果可以获得特权,则将使用 s,否则它将尝试在目标主机的端口 7(Echo)上建立 TCP 连接。
因此,您的问题可能是配置问题,没有足够的权限在客户端计算机上执行此操作,或者如果您的客户端没有执行此操作的权限,则在服务器上出现端口 7 问题。可能两者在你的情况下,你需要解决一方或另一方才能使它起作用。ICMP ECHO REQUESTICMP ECHO REQUEST

我在OSX和Linux客户端上测试了以下内容,并且在测试其他OSX,Linux和Windows Server计算机的可访问性时,它可以正常工作。我没有Windows机器来运行它作为客户端。

import java.io.IOException;
import java.net.InetAddress;

public class IsReachable
{
    public static void main(final String[] args) throws IOException
    {
        final InetAddress host = InetAddress.getByName(args[0]);
        System.out.println("host.isReachable(1000) = " + host.isReachable(1000));
    }
}

我在这里读到的内容。这显然是Windows的限制,并且在Windows 2000之前作为系统调用在Windows上不受支持,因此它默认尝试并连接到端口7,并且在您尝试“访问”的计算机上被阻止。Java 尚不支持新的本机系统调用。权限是针对基于Unix的系统,因为它们需要root来发送数据包。ICMP PINGICMP

如果你想为Windows 2000及更高版本推出自己的Windows原生JNI,可以使用IcmpSendEcho函数ICMP PING


答案 2

当我需要在Windows,Linux和OSX中需要真正的ICMP ping时,我会使用此功能(来自本文)(我还没有测试过其他系统)。

public static boolean isReachableByPing(String host) {
    try{
            String cmd = "";
            if(System.getProperty("os.name").startsWith("Windows")) {   
                    // For Windows
                    cmd = "ping -n 1 " + host;
            } else {
                    // For Linux and OSX
                    cmd = "ping -c 1 " + host;
            }

            Process myProcess = Runtime.getRuntime().exec(cmd);
            myProcess.waitFor();

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

                    return true;
            } else {

                    return false;
            }

    } catch( Exception e ) {

            e.printStackTrace();
            return false;
    }
}

推荐