代码之家  ›  专栏  ›  技术社区  ›  Joe Ijam

无法从get hostname获取主机名

  •  2
  • Joe Ijam  · 技术社区  · 15 年前

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

    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;
    }
    

    结果(不是本地主机)

    getHostAddress : 192.168.2.139
    getHostName : 192.168.2.139
    getCanonicalHostName : 192.168.2.139
    

    结果(本地主机)

    getHostAddress : 127.0.0.1
    getHostName : localhost
    getCanonicalHostName : localhost
    

    谢谢你

    5 回复  |  直到 6 年前
        1
  •  2
  •   Thorbjørn Ravn Andersen    15 年前

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

        2
  •  5
  •   Carl Smotricz    15 年前

    我们已经大致确定了Tangens答案中的问题。

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

    %SystemRoot%\system32\drivers\etc\hosts
    

    是您要查找的文件;本地主机在此处定义。您希望为每个要解析的主机在其中放置一个名称和地址行。

    我从没试过这个。如果它不起作用,你就拿回你的钱。


    更新

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

    另一种选择是操作您自己的DNS服务器。当主机地址改变时,您仍然需要更新IP地址,但是您只需要在一个地方更新IP地址,您就可以在整个网络中获得正向和反向的名称解析。这需要更多的设置,但从长远来看更容易维护。

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

    他们提到“内置”的Microsoft DNS服务器是一个糟糕的解决方案(直到Windows 2003服务器中的解决方案),但至少提到了两个备选方案,一个是商业的,另一个是免费的。bind是目前将大部分互联网连接在一起的东西,以dns为导向,而且他们也有一个windows端口也很好。

        3
  •  2
  •   tangens    15 年前

    inetaddress.getcanonicalhostname()的javadoc说:

    获取此IP地址的完全限定域名。Best-Effort方法,这意味着根据底层系统配置,我们可能无法返回fqdn。

    如果有一个安全管理器,这个方法首先用hostname和-1作为参数调用其checkconnect方法,以查看调用代码是否允许知道这个IP地址的hostname,即连接到主机。 如果不允许该操作,它将返回IP地址的文本表示形式 .

    我看你的系统配置不正确。你在小程序中运行吗?

        4
  •  2
  •   Nick Grealy    6 年前

    正在查找源 InetAddress.getHostName() (太阳JDK8)…

    该方法执行以下逻辑:

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

    *如果步骤3或4 SecurityException / UnknownHostException 返回 获取主机地址()

    对我来说,一步 α2 已成功解析主机名,但在步骤失败 α4 用一个 未知数异常 .


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

    1. 这个 SecurityManager 必须提供访问主机的权限
    2. 您必须能够转发和反向DNS查找 InetAddress
    3. 正向查找详细信息必须与反向查找详细信息匹配

    只有那时Java才会提供主机名。


    或者, 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();
    }
    
        5
  •  1
  •   Andreas Dolk    15 年前

    回复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