获取网络中IP地址的所有主机名

时间:2013-05-17 17:52:45

标签: java networking

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

3 个答案:

答案 0 :(得分:4)

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

// 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地址......你只有一个。它真的需要getHostNames()getAllCanonicalNames()(注意多个)方法来做你想要的。我正在考虑打开一个问题/提交补丁。

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

您将不得不查看java的第三方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));
            }
        }
    }  
}

答案 1 :(得分:0)

嗯,只有一个好方法:调用nslookup或dig或Java进程中的任何东西。

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

使用ProcessBuilder

或更好......

答案 2 :(得分:0)

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

使用lookupAllHostAddr的{​​{1}}方法适用于我,并按主机名返回所有IP地址。也许它也有助于按IP地址查找所有主机名,但似乎这取决于DNS服务器配置。在我的情况下,我甚至无法使用DNSNameService找到所有主机名,因此我无法对其进行测试,因此我对此解决方案不确定。

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

lookupAllHostAddr

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

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

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

  • InetAddress[] ipAddress = new DNSNameService().lookupAllHostAddr("hostname") - 您应该将它添加到JVM启动命令行,如下所示:sun.net.inetaddr.ttl,0表示主机名将被缓存0秒
  • -Dsun.net.inetaddr.ttl=0 - 您应该将所需的值添加到位于networkaddress.cache.ttl
  • 的java.security文件中

此处还可以找到更多信息:

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