Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 获取网络中某个IP地址的所有主机名_Java_Networking - Fatal编程技术网

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

Java 获取网络中某个IP地址的所有主机名,java,networking,Java,Networking,我有一个要求,其中一个IP地址可以有多个主机名映射到它。我尝试查看InetAddress.getAllByName(“10.33.28.55”)但是没有得到想要的结果,它只返回了一个条目nslookup返回所有DNS条目。如何在Java中检索与此IP地址关联的所有主机名?好吧,只有一个好方法:从Java进程调用nslookup或dig或其他任何方法 使用Runtime.getRuntime().exec(..) 或者更好地使用ProcessBuilder…查看InetAddress.getAll

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

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

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


或者更好地使用ProcessBuilder…

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

// if host is an IP address, we won't do further lookup
(见:)

要是JavaDoc这么清晰就好了。它声明“如果提供了文字IP地址,则只检查地址格式的有效性。”。。。我认为这并没有告诉你它不会被查到

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

也就是说,在支持多个PTR记录的情况下,目前似乎没有内置的RDNS查询方法。所有其他的查找方法只是删除返回的第一条记录,这就是您得到的结果

您必须查看java的第三方DNS库(对不起,我没有使用它们的经验)

编辑以添加:我喜欢把事情弄清楚。我没有一个IP handy,它有多个PTR记录来测试这一点,但它应该可以做到这一点

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));
            }
        }
    }  
}
import java.io.IOException;
导入java.util.Properties;
导入javax.naming.Context;
导入javax.naming.NamingException;
导入javax.naming.directory.Attribute;
导入javax.naming.directory.Attributes;
导入javax.naming.directory.InitialDirContext;
公共类应用程序
{
公共静态void main(字符串[]args)引发IOException、NamingException
{
Properties env=新属性();
put(Context.INITIAL\u Context\u工厂,“com.sun.jndi.dns.DnsContextFactory”);
InitialDirContext idc=新的InitialDirContext(env);
字符串ipAddr=“74.125.225.196”;
//将IP转换为in-addr.arpa名称
//196.225.125.74.in-addr.arpa。
字符串[]quads=ipAddr.split(“\\”);
StringBuilder sb=新的StringBuilder();
对于(int i=quads.length-1;i>=0;i--)
{
sb.追加(四元组[i])。追加(“.”);
}
某人附加(“地址arpa”);
ipAddr=sb.toString();
Attributes attrs=idc.getAttributes(ipAddr,新字符串[]{“PTR”});
属性attr=attrs.get(“PTR”);
如果(attr!=null)
{
对于(int i=0;i
这个答案可能会有帮助:

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

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

InetAddress[] ipAddress = new DNSNameService().lookupAllHostAddr("hostname")
另外,从我的角度来看,这个链接可能会很有趣(它也是我上面提到的同一个答案线索中的信息,我只是简单地总结一下):

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

  • sun.net.inetaddr.ttl
    -您应该像这样将其添加到JVM启动命令行:
    -Dsun.net.inetaddr.ttl=0
    ,这里的0表示主机名将被缓存0秒
  • networkaddress.cache.ttl
    -您应该将所需的值添加到位于
    %JRE%\lib\security
也可以在此处找到更多信息:


您是否在与Java代码相同的计算机上运行
nslookup
InetAddress.getAllByName()
应该按照您的要求执行。@BrianRoach:起初我没有这样做,但是,当我在与
nslookup
相同的机器上运行
InetAddress.getAllByName()
时,它仍然在数组中返回1个条目,我期望2个。有趣的是,
getCanonicalHostName()
getHostName()
函数返回了两个不同的值。我原以为这两个值作为数组中的两个元素会出现不同的结果。实际上。。。查看
InetAddress.getAllByName()的源代码。。。如果它是一个IP地址,它实际上不会进行查找,呵呵。您将返回一个包含您提供的IP的
InetAddress
对象。每天学习新的东西;我想我从来没有试过。@BrianRoach:这很有趣。让我看看如果我使用主机名,它会返回什么。我相信我已经知道你需要什么,请看我修改后的答案。我知道这一点,我试图避免这样做,这样我就不必进行解析,也不必依赖Java来返回。似乎我必须使用这种方法,使用
nslookup
host
命令来获取列表并进行必要的解析。这是非常棒的东西。然而,我又回去创建了一个小脚本来为我做这些事情。非常感谢。也许你可以做一个