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

Java DNS解析仅返回IPv4,无法获取IPv6问题求助

解决Java DNS解析无法获取IPv6地址的问题

问题根源

InetAddress.getAllByName的解析结果受以下因素限制:

  • 系统IPv6状态:若操作系统禁用IPv6,Java会优先返回IPv4地址。
  • DNS服务器能力:使用的DNS服务器未返回目标域名的IPv6(AAAA)记录时,自然无法获取IPv6地址。
  • Java网络偏好:默认配置下Java可能优先选择IPv4,即便存在IPv6记录也可能不返回。

解决方案

1. 检查系统与网络配置

  • 确认操作系统已开启IPv6(在Windows/Linux/macOS的网络设置中启用)。
  • 测试DNS服务器的AAAA记录支持:执行命令 nslookup -type=AAAA google.com <你的DNS服务器>,若无返回结果,更换支持IPv6的DNS(如谷歌的2001:4860:4860::8888)。

2. 调整JVM启动参数

运行程序时添加参数,强制Java优先使用IPv6栈或地址:

# 强制使用IPv6栈(彻底切换)
java -Djava.net.preferIPv6Stack=true agin.DNSClient

# 仅优先返回IPv6地址(兼容IPv4)
java -Djava.net.preferIPv6Addresses=true agin.DNSClient

3. 修改代码:自定义DNS解析(更可靠)

当前代码的use dns仅测试DNS可用性,实际解析仍依赖系统默认DNS。可借助Java 9+的Lookup类,实现指定DNS服务器的IPv4/IPv6分别查询:

package agin;

import java.net.*;
import java.util.*;

public class DNSClient {
    private static String dnsServer = null;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.print("> ");
            String input = scanner.nextLine().trim();
            String[] parts = input.split(" ");

            if (parts.length == 0) continue;

            if (parts[0].equalsIgnoreCase("resolve")) {
                if (parts.length != 2) {
                    System.out.println("Utilizare: resolve <domain> sau resolve <ip>");
                    continue;
                }
                resolve(parts[1]);
            } else if (parts[0].equalsIgnoreCase("use") && parts.length == 3 && parts[1].equalsIgnoreCase("dns")) {
                dnsServer = parts[2];
                if (!testDNS(dnsServer)) {
                    System.out.println("Eroare: DNS server invalid.");
                    dnsServer = null;
                } else {
                    System.out.println("DNS server setat la: " + dnsServer);
                }
            } else {
                System.out.println("Comanda necunoscuta!");
            }
        }
    }

    private static void resolve(String query) {
        try {
            List<String> ipv4List = new ArrayList<>();
            List<String> ipv6List = new ArrayList<>();

            // 查询IPv4记录
            Lookup ipv4Lookup = new Lookup(query, Type.A);
            if (dnsServer != null) {
                ipv4Lookup.setServer(new InetSocketAddress(dnsServer, 53));
            }
            InetAddress[] ipv4Addrs = ipv4Lookup.lookup();
            if (ipv4Addrs != null) {
                for (InetAddress addr : ipv4Addrs) {
                    ipv4List.add(addr.getHostAddress());
                }
            }

            // 查询IPv6记录
            Lookup ipv6Lookup = new Lookup(query, Type.AAAA);
            if (dnsServer != null) {
                ipv6Lookup.setServer(new InetSocketAddress(dnsServer, 53));
            }
            InetAddress[] ipv6Addrs = ipv6Lookup.lookup();
            if (ipv6Addrs != null) {
                for (InetAddress addr : ipv6Addrs) {
                    ipv6List.add(addr.getHostAddress());
                }
            }

            System.out.println("Rezultate pentru " + query + ":");
            if (!ipv4List.isEmpty()) {
                System.out.println("Adrese IPv4:");
                ipv4List.forEach(ip -> System.out.println(" - " + ip));
            }
            if (!ipv6List.isEmpty()) {
                System.out.println("Adrese IPv6:");
                ipv6List.forEach(ip -> System.out.println(" - " + ip));
            }
        } catch (Exception e) {
            System.out.println("Nu s-a putut rezolva: " + query);
        }
    }

    private static boolean testDNS(String dns) {
        try {
            Process process = Runtime.getRuntime().exec("nslookup google.com " + dns);
            process.waitFor();
            return process.exitValue() == 0;
        } catch (Exception e) {
            return false;
        }
    }
}

4. 清理冗余代码

原代码中System.out.println(Inet6Address.getByName(query));属于冗余逻辑,且会在无IPv6记录时直接抛出异常中断程序,需删除。

验证步骤

编译修改后的代码,运行后执行以下命令测试:

> use dns 2001:4860:4860::8888
> resolve google.com

此时应能同时获取到IPv4和IPv6地址。

内容的提问来源于stack exchange,提问作者Lungu Mihai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 23:53:19