Java 获取网络中某个IP地址的所有主机名
我有一个要求,其中一个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
InetAddress.getAllByName(“10.33.28.55”)
但是没有得到想要的结果,它只返回了一个条目或者更好地使用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
命令来获取列表并进行必要的解析。这是非常棒的东西。然而,我又回去创建了一个小脚本来为我做这些事情。非常感谢。也许你可以做一个