我有一个要求,即一个IP地址可以映射到多个主机名。我试图查看 InetAddress.getAllByName("10.33.28.55")
,但我没有得到想要的结果,它只返回了一个条目。nslookup
在该IP地址上返回所有DNS条目。如何在Java中检索与此IP地址相关联的所有主机名?
我有一个要求,即一个IP地址可以映射到多个主机名。我试图查看 InetAddress.getAllByName("10.33.28.55")
,但我没有得到想要的结果,它只返回了一个条目。nslookup
在该IP地址上返回所有DNS条目。如何在Java中检索与此IP地址相关联的所有主机名?
查看InetAddress.getAllByName()
的源代码,你会发现如果提供的String
是 IP 地址的文本表示形式,它实际上不会执行 DNS 查询。它只返回一个包含单个 IP 的 InetAddress
对象的数组。甚至在该方法中还有一个方便的注释:
// if host is an IP address, we won't do further lookup
InetAddress
的情况下,它的意义就显而易见了——该类封装了一个 IP 地址,而您只有一个。它真的需要 getHostNames()
和 getAllCanonicalNames()
(请注意复数)方法来执行您所需的操作。我正在考虑提交问题或补丁。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));
}
}
}
}
这个答案可能会有帮助:https://dev59.com/QGUo5IYBdhLWcg3wvRtF#24205035
使用DNSNameService
的lookupAllHostAddr
方法对我很有效,可以按主机名返回所有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
- 您应该将所需值添加到位于%JRE%\lib\security
的java.security文件中此外,还可以在此处找到更多信息:
好的,只有一种好的方法:从Java进程中调用nslookup或dig或其他类似命令。
使用Runtime.getRuntime().exec(..)
或者更好地使用ProcessBuilder...
nslookup
吗?InetAddress.getAllByName()
应该 可以实现你所要求的功能。 - Brian Roachnslookup
相同的机器上运行InetAddress.getAllByName()
时,它仍然在数组中返回1个条目,而我期望有2个。有趣的是,getCanonicalHostName()
和getHostName()
函数返回了2个不同的值。我原以为这2个值会作为数组中的2个元素分别出现。 - devangInetAddress.getAllByName()
的源代码...如果它是一个IP地址,它实际上不会进行查找,呵呵。你会得到一个包含你提供的IP的单个InetAddress
对象。每天都学到新东西;我想我从来没有尝试过这样做。 - Brian Roach