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

Java 網絡編程基礎 (一):InetAddress 類深度解析與實戰用法

     編輯:Java 相關知識

InetAddress 是 Java 網絡 API 的地址抽象核心,封裝 IPv4/IPv6 地址與主機名解析。本文詳細講解:工廠方法創建實例、核心查詢方法、IPv4/IPv6 子類多態、實戰代碼範例、常見坑點。

為什麼不能 new InetAddress()?

InetAddress 無公共構造器,採用 工廠方法模式:靜態方法內部根據解析結果返回 Inet4Address 或 Inet6Address 實例,調用者無需關心具體子類型。

五大核心工廠方法

方法參數返回用途
getByName(String host)主機名/域名/IP字串InetAddress單個地址解析 (最常用)
getAllByName(String host)主機名/域名/IP字串InetAddress[]多 IP 解析 (負載均衡/容灾)
getByAddress(byte[] addr)4字節(IPv4)或16字節(IPv6)InetAddress從原始字節構建,無需 DNS
getByAddress(String host, byte[] addr)主機名 + 原始字節InetAddress綁定主機名與指定 IP
getLocalHost()無InetAddress獲取本機地址 (可能返回環回/站點本地)

核心查詢方法

InetAddress ia = InetAddress.getByName("www.example.com");

System.out.println(ia.getCanonicalHostName()); // 標準主機名 (DNS PTR 記錄)
System.out.println(ia.getHostAddress());       // IP 字串 (如 93.184.216.34)
System.out.println(ia.getHostName());          // 主機名 (可能是傳入的 host)
System.out.println(ia.isLoopbackAddress());    // 是否環回地址 (127.0.0.1 / ::1)
System.out.println(ia.isAnyLocalAddress());    // 是否 0.0.0.0 / ::
System.out.println(ia.isLinkLocalAddress());   // 是否鏈路本地 (169.254.x.x / fe80::)
System.out.println(ia.isSiteLocalAddress());   // 是否站點本地 (私有網段,IPv6 已棄用)
System.out.println(ia.isMulticastAddress());   // 是否組播地址 (224.0.0.0/4 / ff00::/8)
System.out.println(ia.isMCGlobal());           // 是否全球組播
System.out.println(ia.isMCNodeLocal());        // 是否節點本地組播
System.out.println(ia.isMCLinkLocal());        // 是否鏈路本地組播
System.out.println(ia.isMCSiteLocal());        // 是否站點本地組播
System.out.println(ia.isMCOrgLocal());         // 是否組織本地組播

完整 Demo:命令行解析工具

import java.net.*;

public class InetAddressDemo {
    public static void main(String[] args) {
        String host = args.length > 0 ? args[0] : "localhost";
        try {
            InetAddress[] addresses = InetAddress.getAllByName(host);
            System.out.println("解析 " + host + " 共 " + addresses.length + " 個地址:");
            for (int i = 0; i < addresses.length; i++) {
                InetAddress ia = addresses[i];
                System.out.printf("  [%d] %s (%s)%n", 
                    i + 1, ia.getHostAddress(), 
                    ia instanceof Inet4Address ? "IPv4" : "IPv6");
                System.out.println("      Canonical: " + ia.getCanonicalHostName());
                System.out.println("      Loopback: " + ia.isLoopbackAddress());
                System.out.println("      Multicast: " + ia.isMulticastAddress());
            }
        } catch (UnknownHostException e) {
            System.err.println("解析失敗: " + e.getMessage());
        }
    }
}

關鍵坑點與最佳實踐

坑點現象解法
getLocalHost() 返回 127.0.0.1/etc/hosts 把主機名映射到環回檢查 /etc/hosts,確保主機名映射真實 LAN IP;或遍歷 NetworkInterface 獲取非環回地址
DNS 解析緩存導致 IP 變更不生效JVM 緩存正/負解析結果啟動參數 -Dsun.net.inetaddr.ttl=30 (正向 30s) -Dsun.net.inetaddr.negative.ttl=10 (負向 10s),0=永不緩存
IPv6 環境下 getByName 返回 IPv6 優先雙棧系統 IPv6 優先若需強制 IPv4,用 Inet4Address.getByName() (需自行過濾) 或系統層面配置
安全管理器限制非受信代碼調用 getByName 拋 SecurityException簽名 JAR / 配置 policy 文件授予 permission java.net.SocketPermission "*", "resolve"

進階:NetworkInterface 獲取本機所有網卡 IP

public static void printAllLocalAddresses() throws SocketException {
    Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
    while (interfaces.hasMoreElements()) {
        NetworkInterface ni = interfaces.nextElement();
        if (!ni.isUp() || ni.isLoopback() || ni.isVirtual()) continue;
        Enumeration addresses = ni.getInetAddresses();
        while (addresses.hasMoreElements()) {
            InetAddress ia = addresses.nextElement();
            if (ia instanceof Inet4Address) {
                System.out.println(ni.getName() + " → " + ia.getHostAddress());
            }
        }
    }
}

總結

InetAddress 是網絡編程的「身份證工廠」。掌握:工廠方法選擇 (單/多 IP)、核心查詢方法、DNS 緩存控制、本機網卡枚舉,即可靈活處理地址解析、服務發現、網絡診斷等場景。

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