首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 域名解析 IP 完整範例:InetAddress 獲取本機與遠端主機位址

     編輯:Java 相關知識

核心 API:java.net.InetAddress

JDK 內建類別,提供 DNS 解析、本機位址獲取、主機名稱查詢等功能,無需第三方依賴。

完整工具類

package com.example.net;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;

public final class DnsResolver {

    private DnsResolver() {}

    /** 解析域名回傳所有 IP(IPv4/IPv6) */
    public static InetAddress[] resolveAll(String hostname) {
        try {
            return InetAddress.getAllByName(hostname);
        } catch (UnknownHostException e) {
            return new InetAddress[0];
        }
    }

    /** 解析域名回傳第一個 IP(通常為 IPv4) */
    public static InetAddress resolveFirst(String hostname) {
        InetAddress[] addrs = resolveAll(hostname);
        return addrs.length > 0 ? addrs[0] : null;
    }

    /** 取得本機所有網卡位址 */
    public static InetAddress[] getLocalAddresses() {
        try {
            return InetAddress.getAllByName(InetAddress.getLocalHost().getHostName());
        } catch (UnknownHostException e) {
            return new InetAddress[0];
        }
    }

    /** 取得本機首選 IPv4 位址 */
    public static String getLocalIpv4() {
        return Arrays.stream(getLocalAddresses())
            .filter(a -> a instanceof java.net.Inet4Address)
            .map(InetAddress::getHostAddress)
            .findFirst()
            .orElse("127.0.0.1");
    }

    public static void main(String[] args) {
        String domain = "www.baidu.com";

        System.out.println("=== 本機資訊 ===");
        System.out.println("主機名: " + getLocalHostName());
        System.out.println("IPv4:   " + getLocalIpv4());
        System.out.println("所有 IP: " + Arrays.toString(getLocalAddresses()));

        System.out.println("\n=== 遠端解析: " + domain + " ===");
        InetAddress[] remote = resolveAll(domain);
        for (InetAddress addr : remote) {
            System.out.printf("  %s (%s)%n", addr.getHostAddress(),
                addr instanceof java.net.Inet4Address ? "IPv4" : "IPv6");
        }

        InetAddress first = resolveFirst(domain);
        if (first != null) {
            System.out.println("\n首選 IP: " + first.getHostAddress());
        }
    }

    private static String getLocalHostName() {
        try { return InetAddress.getLocalHost().getHostName(); }
        catch (UnknownHostException e) { return "unknown"; }
    }
}

關鍵方法對照表

方法回傳說明
getByName(host)InetAddress解析單一 IP(取第一筆),會拋出 UnknownHostException。
getAllByName(host)InetAddress[]解析所有 IP(含 IPv4/IPv6、多張網卡、負載均衡多 IP)。
getLocalHost()InetAddress取得本機回環/首張網卡位址,依 OS 實作而定。
getHostAddress()StringIP 字串格式(IPv4: x.x.x.x,IPv6: xxxx:xxxx:...)。
getHostName()String主機名稱(可能觸發反向 DNS 查詢,較慢)。
isReachable(timeout)booleanICMP/TCP 探測主機是否可達(需權限,跨平台行為不一)。

進階應用:DNS 快取與 TTL 控制

  • JDK 內建 DNS 快取,預設 TTL 為 networkaddress.cache.ttl 安全屬性(預設 -1 永久快取)。
  • 生產環境建議設定有限 TTL:-Dsun.net.inetaddr.ttl=60(秒)。
  • 若需完全控制(如自定義 DNS 伺服器、DNS-over-HTTPS),請使用 dnsjava 或 Netty Resolver。

常見問題

安全提醒

解析結果不可完全信任(DNS 劫持、快取投毒)。安全敏感場景請結合:

  • IP 白名單驗證
  • TLS 證書驗證(HostnameVerifier)
  • Certificate Pinning
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
現象原因解決
解析極慢/卡住DNS 伺服器無回應、IPv6 優先但網路不支援設定 -Djava.net.preferIPv4Stack=true 或配置可靠 DNS (8.8.8.8/114.114.114.114)
取到 127.0.0.1/etc/hosts 將主機名指向回環修正 /etc/hosts,或用 getAllByName 過濾非回環位址
UnknownHostException域名不存在、DNS 故障、離線捕獲異常、重試、降級用備用 IP