【问题标题】:Why isn't Java's InetAddress class resolving ipv6 addresses to their FQDN?为什么 Java 的 InetAddress 类不将 ipv6 地址解析为其 FQDN?
【发布时间】:2011-06-03 02:56:22
【问题描述】:

我正在尝试使用 Java 编写一个简单的程序,给定版本 4 或 6 格式的 IP,将返回其 FQDN。以下代码在给定 ipv4 地址时可以正常工作,但只会在输入 ipv6 地址时返回给定地址。

InetAddress inet;
try { inet = InetAddress.getByName(theIpAddress); }
catch(UnknownHostException e) { System.out.println("Unknown Host"); return; }

System.out.println(inet.getHostAddress(););
System.out.println(inet.getHostName(););

每当我输入 ipv6 时,getHostName() 只会返回相同的 ipv6,即使我知道 ipv6 将解析为 FQDN。此外,如果我输入 ipv6 主机名,例如 ipv6.google.com,代替 IpAddress,则会发生异常。

我是这个东西的新手,所以很感激任何帮助。谢谢。

【问题讨论】:

  • 您的主机/网络肯定有 IPv6 DNS 工作吗? nslookup 是否得到正确的结果?

标签: java networking dns ipv6 fqdn


【解决方案1】:

问题实际上是我运行的 Java 版本。将 Java 从 1.6.21 更新到 1.6.23,允许 ipv6s 解析为其 FQDN。

【讨论】:

  • 您可能希望将自己的答案标记为“答案”。单击它旁边的复选标记(将其变为绿色)。
【解决方案2】:

我快速调查了 java 8、Windows 7 中主机名 ipv6 解析的情况。 看起来“默认”NameService 根本不适用于 ipv6! 但! Java 附带了另一个名为“dns,sun”的基于 JNDI 的 NameService 实现。 因此,如果您使用任一方式启用它

-Dsun.net.spi.nameservice.provider.1=dns,sun

System.setProperty("sun.net.spi.nameservice.provider.1", "dns,sun");

您将获得像这样的 v4 和 v6 地址的双向 ip 主机名解析

InetAddress.getAllByName(...)
address.getHostName()

更多关于java ipv6的信息你可以在这里找到http://docs.oracle.com/javase/8/docs/technotes/guides/net/ipv6_guide/

【讨论】:

    【解决方案3】:

    试试inet.getCanonicalHostName();,它“获取此 IP 地址的完全限定域名。”

    如果您使用 InetAddress.getByName() 构造 InetAddress,getHostName() 将返回您构造它的内容。 getCanonicalHostName() 强制反向名称查找。

    【讨论】:

    • 我实际上已经尝试过了,但没有成功。还是同样的问题。
    【解决方案4】:

    使用java.net.InetAddress不可能有ipv6和ipv4名称解析等。像getByName这样的一堆静态方法将查找委托给Inet4(or 6)AddressImpl的实例

    public native InetAddress[] lookupAllHostAddr(String hostname) throws UnknownHostException;
    

    现在有趣的是 a) 所有这些都是私有的/包本地的,因此无法将 impl 类注入 InetAddress 类 b) Inet4(或 6)AddressImpl 类本身就是包本地的。所以没有办法说,即时进行 ipv4 或 ipv6 查找/名称解析。我不明白这些类的所有扩展点都被阻止的方式,这使得它们的使用和灵活性非常有限。 真正的黑魔法发生在这里,InetAddress 类静态初始化 impls,方法 isIPv6Supported() 的结果依赖于什么?我的 Linux 设置支持 ipv6,我可以对 ipv6 主机名(如 ipv6.google.com)进行 dns 查找。 如果有人能指出我在 java 中用于 ipv4/v6 实用程序(如查找等)的良好网络库的方向,将不胜感激。

    class InetAddressImplFactory {
    
        static InetAddressImpl create() {
        Object o;
        if (isIPv6Supported()) {
            o = InetAddress.loadImpl("Inet6AddressImpl");
        } else {
            o = InetAddress.loadImpl("Inet4AddressImpl");
        }
        return (InetAddressImpl)o;
        }
    
        static native boolean isIPv6Supported();
    }
    

    【讨论】:

    • 这大部分是不正确的。 InetAddress 将返回适当的 IPv4/6 实现类。这就是设计的全部原因。这也不是一个答案。