如果无法通过 Java 中的 DNS 解析,如何获取本地主机名?

2022-09-03 05:25:05

这听起来像是以前应该问过的事情,而且它有某种程度上,但我希望获得机器的本地主机名和IP地址,即使它无法通过DNS(在Java中)解析。

我可以通过迭代来获得本地IP地址而无需解决。NetworkInterfaces.getNetworkInterfaces()

我发现这个问题的任何答案都表明使用getLocalHost()

InetAddress localhost = java.net.InetAddress.getLocalHost();
hostName = localhost.getHostName();

但这会引发一个如果主机名无法通过DNS解析。UnknownHostException

在没有在后台进行DNS查找的情况下,没有办法获取本地主机名吗?

编辑:检索到的 IP 地址是 10.4.168.23 例外情况是(主机名更改为伪匿名),并且 hosts 文件不包含主机名。但是它确实知道它的主机名,所以我不确定为什么我不能在不抛出异常的情况下得到它。java.net.UnknownHostException: cms1.companyname.com: cms1.companyname.com


答案 1

是的,在Java中应该有一种方法可以在不诉诸名称服务查找的情况下获取主机名,但不幸的是没有。

但是,您可以执行如下操作:

if (System.getProperty("os.name").startsWith("Windows")) {
    // Windows will always set the 'COMPUTERNAME' variable
    return System.getenv("COMPUTERNAME");
} else {
    // If it is not Windows then it is most likely a Unix-like operating system
    // such as Solaris, AIX, HP-UX, Linux or MacOS.

    // Most modern shells (such as Bash or derivatives) sets the 
    // HOSTNAME variable so lets try that first.
    String hostname = System.getenv("HOSTNAME");
    if (hostname != null) {
       return hostname;
    } else {

       // If the above returns null *and* the OS is Unix-like
       // then you can try an exec() and read the output from the 
       // 'hostname' command which exist on all types of Unix/Linux.

       // If you are an OS other than Unix/Linux then you would have 
       // to do something else. For example on OpenVMS you would find 
       // it like this from the shell:  F$GETSYI("NODENAME") 
       // which you would probably also have to find from within Java 
       // via an exec() call.

       // If you are on zOS then who knows ??

       // etc, etc
    }
}

这将使您在传统的Sun JDK平台(Windows,Solaris,Linux)上获得100%的需求,但是如果您的操作系统更加外向(从Java的角度来看),则变得不那么容易。请参阅代码示例中的注释。

我希望有更好的方法。


答案 2

这个问题很老了,但不幸的是仍然相关,因为在Java中获取机器的主机名仍然不容易。以下是我在不同系统上进行一些测试运行的解决方案:

public static void main(String[] args) throws IOException {
        String OS = System.getProperty("os.name").toLowerCase();

        if (OS.indexOf("win") >= 0) {
            System.out.println("Windows computer name throguh env:\"" + System.getenv("COMPUTERNAME") + "\"");
            System.out.println("Windows computer name through exec:\"" + execReadToString("hostname") + "\"");
        } else {
            if (OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0) {
                System.out.println("Linux computer name throguh env:\"" + System.getenv("HOSTNAME") + "\"");
                System.out.println("Linux computer name through exec:\"" + execReadToString("hostname") + "\"");
                System.out.println("Linux computer name through /etc/hostname:\"" + execReadToString("cat /etc/hostname") + "\"");
            }
        }
    }

    public static String execReadToString(String execCommand) throws IOException {
        Process proc = Runtime.getRuntime().exec(execCommand);
        try (InputStream stream = proc.getInputStream()) {
            try (Scanner s = new Scanner(stream).useDelimiter("\\A")) {
                return s.hasNext() ? s.next() : "";
            }
        }
    }

不同操作系统的结果:

开放使用 13.1

Linux computer name throguh env:"machinename"
Linux computer name through exec:"machinename
"
Linux computer name through /etc/hostname:""

Ubuntu 14.04 LTS这个有点奇怪,因为返回正确的主机名,但不会(然而,这可能只是我的环境的问题):echo $HOSTNAMESystem.getenv("HOSTNAME")

Linux computer name throguh env:"null"
Linux computer name through exec:"machinename
"
Linux computer name through /etc/hostname:"machinename
"

视窗 7

Windows computer name throguh env:"MACHINENAME"
Windows computer name through exec:"machinename
"

机器名称已被替换为(一些)匿名化,但我保留了大写和结构。请注意,在执行 时需要注意额外的换行符,在某些情况下,您可能需要考虑它。hostname