如何用dnsjava库通过IP获取主机名?代码执行异常求助
问题原因及修复方案
核心问题分析
你的代码出现问题主要有两个关键原因:
错误的查询记录类型
反向DNS查询(通过IP获取主机名)仅需要查询 Type.PTR 记录。你当前循环查询了Type.A、Type.AAAA和Type.PTR,但ReverseMap.fromAddress()生成的69.1.101.151.in-addr.arpa是反向解析专用域,这个域下不存在A/AAAA记录,所以这两类查询必然返回空或抛出异常,还会干扰你对PTR查询结果的判断。未排查查询错误信息
当Lookup.run()返回null时,你没有调用lookUp.getErrorString()查看具体错误原因,这会导致无法定位PTR查询失败的真实问题(比如DNS服务器超时、目标IP无PTR记录等)。
另外,针对你使用的OpenDNS服务器(208.67.222.222),该服务器支持反向解析,且151.101.1.69确实存在PTR记录(151.101.1.69.cloudflare.com.),所以查询本身是可行的。
修复后的代码示例
方法一:使用Lookup类
import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; import org.xbill.DNS.Lookup; import org.xbill.DNS.PTRRecord; import org.xbill.DNS.Record; import org.xbill.DNS.Resolver; import org.xbill.DNS.ReverseMap; import org.xbill.DNS.SimpleResolver; import org.xbill.DNS.Type; public class IPToName { public static void main(String[] args) throws UnknownHostException { findHostNameWithLookup(); } public static void findHostNameWithLookup() throws UnknownHostException { // 初始化OpenDNS解析器 Resolver resolver = new SimpleResolver(InetAddress.getByName("208.67.222.222")); // 设置超时时间(可选,避免无限等待) resolver.setTimeout(5); Collection<String> hostNames = new ArrayList<>(); // 仅查询PTR记录 final Lookup lookUp = new Lookup(ReverseMap.fromAddress("151.101.1.69"), Type.PTR); lookUp.setResolver(resolver); Record[] records = lookUp.run(); // 检查查询错误 if (lookUp.getErrorString() != null) { System.err.println("查询错误: " + lookUp.getErrorString()); return; } if (records != null) { for (Record record : records) { if (record instanceof PTRRecord) { hostNames.add(record.rdataToString()); } } } hostNames.stream().forEach(System.out::println); } }
方法二:使用LookupSession类
import java.net.InetAddress; import java.net.UnknownHostException; import java.util.concurrent.CompletableFuture; import org.xbill.DNS.Record; import org.xbill.DNS.ReverseMap; import org.xbill.DNS.SimpleResolver; import org.xbill.DNS.Type; import org.xbill.DNS.lookup.LookupResult; import org.xbill.DNS.lookup.LookupSession; public class IPToName { public static void main(String[] args) throws UnknownHostException { findHostNameWithLookupSession(); } public static void findHostNameWithLookupSession() throws UnknownHostException { LookupSession lookupSession = LookupSession.builder() .resolver(new SimpleResolver(InetAddress.getByName("208.67.222.222"))) .build(); // 仅异步查询PTR记录 CompletableFuture<LookupResult> ptrLookup = lookupSession .lookupAsync(ReverseMap.fromAddress("151.101.1.69"), Type.PTR) .toCompletableFuture(); try { LookupResult result = ptrLookup.join(); for (Record record : result.getRecords()) { System.out.println(record.rdataToString()); } } catch (Throwable exc) { System.err.println("查询失败: " + exc.getMessage()); exc.printStackTrace(); } } }
额外说明
- 若仍出现查询失败,可尝试更换DNS服务器(比如公共DNS 8.8.8.8或114.114.114.114),部分DNS服务器可能对反向解析做了限制。
- 并非所有IP都有PTR记录,很多动态IP或CDN节点可能没有配置反向解析,这种情况下查询会返回"NXDOMAIN"(域名不存在)错误。
内容的提问来源于stack exchange,提问作者Edgar Becker
相关产品推荐
相关产品推荐

