无法从getHostName获取主机名

时间:2009-12-14 06:41:02

标签: java

我正在尝试使用此方法获取主机名/计算机名称。不幸的是,我只能获得localhost而不是其他计算机。

private String getHostName(String _strIP) {
    try {
        InetAddress inetAddress = InetAddress.getByName(_strIP);
        System.out.println("getHostAddress : " + inetAddress.getHostAddress());
        System.out.println("getHostName : " + inetAddress.getHostName());
        System.out.println("getCanonicalHostName : " + inetAddress.getCanonicalHostName());
        return inetAddress.getHostName();            
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }
    return strDefaultHostName;
}

结果(不是localhost)

getHostAddress : 192.168.2.139
getHostName : 192.168.2.139
getCanonicalHostName : 192.168.2.139

结果(localhost)

getHostAddress : 127.0.0.1
getHostName : localhost
getCanonicalHostName : localhost

谢谢

5 个答案:

答案 0 :(得分:5)

我们已经大致确定了tangens回答的问题。

我认为您可以通过将主机名放入主机文件中来解决问题。

%SystemRoot%\system32\drivers\etc\hosts

是您要查找的文件; localhost在这里定义。您希望为每个要解析的主机添加名称和地址行。

我从未尝试过这个。如果它不起作用,你会收回你的钱。


<强>更新

以上是“快速入侵”解决方案。这基本上要求每当有人手动更改您感兴趣的主机的IP地址时,必须同时更改任何想要访问这些主机的计算机上的hosts文件。

另一种方法是运行您自己的DNS服务器。当主机的地址发生变化时,您仍需要更新IP地址,但只需在一个地方进行更新,即可在整个网络中同时获得正向和反向名称解析。这需要更多的设置,但从长远来看更容易维护。

这是一个非常有用的参考:http://www.dns.net/dnsrd/servers/windows.html

他们提到“内置”Microsoft DNS服务器是一个糟糕的解决方案(直到Windows 2003 Server中的一个),但提到至少两个选择,一个商业和一个免费。 BIND目前正在将大部分互联网连接在一起,DNS方面也是如此,而且它们也拥有Windows端口也很棒。

答案 1 :(得分:2)

InetAddress.getCanonicalHostName()的javadoc说:

  

获取此IP地址的完全限定域名。尽力而为方法,这意味着我们可能无法返回FQDN,具体取决于底层系统配置。

     

如果有安全管理器,则此方法首先使用hostname和-1作为其参数调用其checkConnect方法,以查看是否允许调用代码知道此IP地址的主机名,即连接到主机。 如果不允许操作,则会返回IP地址的文本表示

我看起来你的系统配置不正确。你是从applet中运行的吗?

答案 2 :(得分:2)

您的DNS已损坏。然后返回IP号码。

答案 3 :(得分:2)

查看InetAddress.getHostName()(Sun JDK8)...

的来源

该方法执行以下逻辑:

  
      
  1. 循环浏览可用的sun.net.spi.nameservice.NameService's
  2.   
  3. 执行反向DNS查找 - 例如192.168.0.23 -> frodo.baggins.com.au
  4.   
  5. *使用java.lang.SecurityManager进行检查,看看“我们是否有权连接”主机名
  6.   
  7. *对主机名执行正向DNS查找,以防止欺骗 - 例如frodo.baggins.com.au -> 192.168.0.99
  8.   
  9. 如果正向查找结果与原始地址匹配(例如192.168.0.23 == 192.168.0.99?),则返回主机名,否则返回getHostAddress()
  10.         

    *如果第3步或第4步引发SecurityException / UnknownHostException,请返回getHostAddress()

对我来说,步骤#2 已成功解析主机名,但在步骤#4 时失败并显示UnknownHostException

TLDR;您必须满足以下所有要求:

  1. SecurityManager必须提供访问主机的权限
  2. 您必须能够转发和撤消InetAddress
  3. 的DNS查询
  4. 正向查找详细信息必须与反向查找详细信息匹配
  5. 只有这样,Java才能为您提供主机名。

    OR,you could bypass these steps with the following method,只需获取主机名。

    @SuppressWarnings("unchecked")
    public static String getHostName(InetAddress addr) {
        String host = null;
        List<NameService> nameServicesImpl = new ArrayList<>();
        try {
            // do naughty things...
            Field nameServices = InetAddress.class.getDeclaredField("nameServices");
            nameServices.setAccessible(true);
            nameServicesImpl = (List<NameService>) nameServices.get(null);
        } catch (Throwable t) {
            throw new RuntimeException("Got caught doing naughty things.", t);
        }
        for (NameService nameService : nameServicesImpl) {
            try {
                // lookup the hostname...
                host = nameService.getHostByAddr(addr.getAddress());
            } catch (Throwable t) {
                // NOOP: problem getting hostname from this name service, continue looping...
            }
        }
        return host != null ? host : addr.getHostAddress();
    }
    

答案 4 :(得分:1)

Carl Smotricz的回复反馈

很好的答案,但我们仍然不知道主机名是否已更新... 这就像我们硬编码一样。

无论如何,非常感谢你

# Copyright (c) 1993-1999 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

127.0.0.1       localhost
192.168.2.139       dev-testing