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

Java 獲取域名 IP 地址:InetAddress 完整用法與多 IP 處理

     編輯:Java 相關知識

核心 API:java.net.InetAddress

InetAddress 代表 IP 地址(IPv4/IPv6),提供本機地址獲取、域名解析、主機名反查等功能。

完整實作範例

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

public class DomainIpResolver {
    public static void main(String[] args) {
        // 1. 獲取本機 IP
        try {
            InetAddress local = InetAddress.getLocalHost();
            System.out.println("本機主機名:" + local.getHostName());
            System.out.println("本機 IP:" + local.getHostAddress());
        } catch (UnknownHostException e) {
            System.err.println("獲取本機地址失敗:" + e.getMessage());
        }

        // 2. 解析域名所有 IP(支援多 IP、CDN、負載均衡)
        String domain = "www.google.com"; // 測試域名
        System.out.println("\n解析域名:" + domain);
        resolveDomain(domain);

        // 3. 反查:IP 獲取主機名
        try {
            InetAddress ip = InetAddress.getByName("8.8.8.8");
            System.out.println("\n8.8.8.8 主機名:" + ip.getHostName());
        } catch (UnknownHostException e) {
            System.err.println("反查失敗:" + e.getMessage());
        }
    }

    /** 解析域名並列印所有 IP */
    public static void resolveDomain(String domain) {
        try {
            InetAddress[] addresses = InetAddress.getAllByName(domain);
            System.out.println("共解析到 " + addresses.length + " 個 IP:");
            for (int i = 0; i < addresses.length; i++) {
                InetAddress addr = addresses[i];
                System.out.printf("  IP %d: %s (%s)%n", 
                    i + 1, 
                    addr.getHostAddress(), 
                    addr instanceof java.net.Inet6Address ? "IPv6" : "IPv4");
            }
        } catch (UnknownHostException e) {
            System.err.println("域名解析失敗:" + e.getMessage());
        }
    }
}

關鍵方法對照表

方法用途回傳異常
getLocalHost()獲取本機地址InetAddressUnknownHostException
getByName(host)解析域名/IP,取第一個InetAddressUnknownHostException
getAllByName(host)解析域名所有 IPInetAddress[]UnknownHostException
getHostAddress()取得 IP 字串String-
getHostName()取得主機名(反查 DNS PTR)String-
isReachable(timeout)ICMP/TCP 探測連通性booleanIOException

進階場景與最佳實踐

1. 域名解析緩存控制

JVM 預設緩存正向解析結果 永久(networkaddress.cache.ttl=-1),負向緩存 10 秒。生產環境需調整:

// 安全策略文件或啟動參數
-Dsun.net.inetaddr.ttl=60        # 正向緩存 60 秒
-Dsun.net.inetaddr.negative.ttl=10 # 負向緩存 10 秒

或代碼動態設置(需權限):

java.security.Security.setProperty("networkaddress.cache.ttl", "60");

2. IPv4/IPv6 雙棧環境處理

// 只取 IPv4
Arrays.stream(InetAddress.getAllByName(domain))
      .filter(addr -> addr instanceof java.net.Inet4Address)
      .findFirst()
      .ifPresent(addr -> System.out.println("IPv4: " + addr.getHostAddress()));

3. 非阻塞異步解析(Java 9+)

// 使用 CompletableFuture 避免阻塞主執行緒
CompletableFuture.supplyAsync(() -> {
    try { return InetAddress.getAllByName(domain); }
    catch (UnknownHostException e) { throw new RuntimeException(e); }
}).thenAccept(addrs -> {
    // 異步處理結果
});

4. 容器化環境注意事項

  • getLocalHost() 在 Docker 中可能返回容器內部 IP(如 172.17.0.2)而非宿主機 IP。
  • 服務發現建議使用 Consul、Eureka、Kubernetes DNS 而非依賴本機解析。

常見錯誤排查

錯誤原因解決
UnknownHostExceptionDNS 解析失敗、域名錯誤、網路不通檢查 /etc/resolv.conf、nslookup 驗證、防火牆
返回 127.0.0.1/etc/hosts 配置錯誤、主機名映射回環修正 hosts、檢查 hostname 指令
緩存導致 IP 不更新JVM DNS 緩存 TTL 過長設置 networkaddress.cache.ttl

總結

InetAddress 是 Java 網路編程基石,掌握 getAllByName 多 IP 處理、緩存控制、IPv6 適配、容器化環境坑點,能構建健壯的網路服務發現與通訊模組。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved