You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用dnsjava库通过IP获取主机名?代码执行异常求助

问题原因及修复方案

核心问题分析

你的代码出现问题主要有两个关键原因:

  1. 错误的查询记录类型
    反向DNS查询(通过IP获取主机名)仅需要查询 Type.PTR 记录。你当前循环查询了Type.A、Type.AAAA和Type.PTR,但ReverseMap.fromAddress()生成的69.1.101.151.in-addr.arpa是反向解析专用域,这个域下不存在A/AAAA记录,所以这两类查询必然返回空或抛出异常,还会干扰你对PTR查询结果的判断。

  2. 未排查查询错误信息
    当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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 02:46:22