4

我有一个要求,其中一个 IP 地址可以有多个映射到它的主机名。我尝试调查,InetAddress.getAllByName("10.33.28.55")但没有得到想要的结果,它只返回一个条目。nslookup在 IP 地址上返回所有 DNS 条目。如何在 Java 中检索与此 IP 地址关联的所有主机名?

4

3 回答 3

4

查看源代码,您会发现如果提供的是 IP 地址的文本表示InetAddress.getAllByName(),它实际上不会执行 DNS 查询。String它只是返回一个数组,其中包含一个InetAdddress包含 IP 的对象。他们甚至在方法中添加了一个方便的注释:

// if host is an IP address, we won't do further lookup

(见:http: //javasourcecode.org/html/open-source/jdk/jdk-6u23/java.net/InetAddress.java.html

要是 JavaDoc 这么清楚就好了。它指出“如果提供了文字 IP 地址,则仅检查地址格式的有效性。” ...我认为这并没有告诉你它不会被查找。

但是,考虑一下...在以下上下文中是有意义的InetAddress-该类封装了一个IP地址...您只有一个IP地址。它确实需要getHostNames()并且getAllCanonicalNames()(注意多个)方法可以满足您的要求。我正在考虑打开一个问题/提交一个补丁。

也就是说,目前似乎没有内置的方法来支持多个 PTR 记录的 RDNS 查询。所有其他查找方法只是简单地删除返回的第一条记录,这就是你得到的。

您将不得不研究用于 java 的 3rd 方 DNS 库(对不起,我没有使用它们的经验)。

编辑添加:我喜欢弄清楚事情。我没有手边有多个 PTR 记录的 IP 来测试它,但它应该可以解决问题。

import java.io.IOException;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.InitialDirContext;

public class App
{
    public static void main(String[] args) throws IOException, NamingException
    {
        Properties env = new Properties();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
        InitialDirContext idc = new InitialDirContext(env);

        String ipAddr = "74.125.225.196";

        // Turn the IP into an in-addr.arpa name
        // 196.225.125.74.in-addr.arpa.
        String[] quads = ipAddr.split("\\.");
        StringBuilder sb = new StringBuilder();
        for (int i = quads.length - 1; i >= 0; i--) 
        {
            sb.append(quads[i]).append(".");
        }
        sb.append("in-addr.arpa.");
        ipAddr = sb.toString();

        Attributes attrs = idc.getAttributes(ipAddr, new String[] {"PTR"});
        Attribute attr = attrs.get("PTR");

        if (attr != null) 
        {
            for (int i = 0; i < attr.size(); i++)
            {
                System.out.println((String)attr.get(i));
            }
        }
    }  
}
于 2013-05-17T19:17:05.030 回答
0

好吧,只有一种好方法:从 Java 进程调用 nslookup 或 dig 或其他任何方法。

使用 Runtime.getRuntime().exec(..)

或使用 ProcessBuilder 更好...

于 2013-05-17T18:08:45.010 回答
0

这个答案可能会有所帮助:https ://stackoverflow.com/a/24205035/8026752

使用适用于我的lookupAllHostAddr方法DNSNameService,并按主机名返回所有 IP 地址。也许它也有助于通过 IP 地址查找所有主机名,但这似乎取决于 DNS 服务器配置。在我的情况下,我什至找不到所有使用的主机名nslookup,所以我无法测试它,所以我不确定这个解决方案。

一个建议是这lookupAllHostAddr不是静态方法,所以你应该像这样使用它:

InetAddress[] ipAddress = new DNSNameService().lookupAllHostAddr("hostname")

另外,从我的角度来看,这个链接可能很有趣(它也是来自我上面提到的同一个答案线程的信息,我只是总结一下):

https://docs.oracle.com/javase/8/docs/technotes/guides/net/properties.html

在链接页面上,您可以找到禁用查找缓存的属性:

  • sun.net.inetaddr.ttl- 你应该像这样将它添加到 JVM 启动命令行:-Dsun.net.inetaddr.ttl=0,这里的 0 表示主机名将被缓存 0 秒
  • networkaddress.cache.ttl- 您应该将所需的值添加到位于的 java.security 文件中%JRE%\lib\security

更多信息也可以在这里找到:

http://www.rgagnon.com/javadetails/java-0445.html

于 2017-07-21T16:14:33.447 回答