我有一个要求,其中一个 IP 地址可以有多个映射到它的主机名。我尝试调查,InetAddress.getAllByName("10.33.28.55")
但没有得到想要的结果,它只返回一个条目。nslookup
在 IP 地址上返回所有 DNS 条目。如何在 Java 中检索与此 IP 地址关联的所有主机名?
3 回答
查看源代码,您会发现如果提供的是 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));
}
}
}
}
好吧,只有一种好方法:从 Java 进程调用 nslookup 或 dig 或其他任何方法。
使用 Runtime.getRuntime().exec(..)
或使用 ProcessBuilder 更好...
这个答案可能会有所帮助: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
更多信息也可以在这里找到: