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

Java 獲取服務器 IP 與 MAC 地址:跨平台生產級實現

     編輯:Java 相關知識

核心挑戰:多網卡、虛擬網卡、回環地址過濾

服務器常擁有多塊網卡(物理、虛擬、Docker、VPN),單純 InetAddress.getLocalHost() 往往返回 127.0.0.1 或錯誤綁定。需遍歷 NetworkInterface,過濾回環、非 UP、虛擬介面,精準定位業務 IP 與對應 MAC。

工具類:NetworkIdentityUtil

public final class NetworkIdentityUtil {
    private static final Pattern IPV4_PATTERN = Pattern.compile("(\\d{1,3}\\.){3}\\d{1,3}");

    private NetworkIdentityUtil() {}

    /** 獲取首個合適的 IPv4 地址(非回環、非鏈路本地) */
    public static String getPrimaryIpv4() {
        return getAllIpv4s().stream().findFirst().orElse(null);
    }

    /** 獲取所有合適的 IPv4 列表 */
    public static List<String> getAllIpv4s() {
        List<String> ips = new ArrayList<>();
        try {
            Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
            while (nis.hasMoreElements()) {
                NetworkInterface ni = nis.nextElement();
                if (!isValidInterface(ni)) continue;

                Enumeration<InetAddress> ias = ni.getInetAddresses();
                while (ias.hasMoreElements()) {
                    InetAddress ia = ias.nextElement();
                    if (isValidIpv4(ia)) {
                        ips.add(ia.getHostAddress());
                    }
                }
            }
        } catch (SocketException e) {
            log.warn("獲取網卡信息失敗", e);
        }
        return ips;
    }

    /** 獲取首個有效網卡的 MAC */
    public static String getPrimaryMac() {
        return getAllMacs().stream().findFirst().orElse(null);
    }

    /** 獲取所有有效網卡 MAC 列表 */
    public static List<String> getAllMacs() {
        List<String> macs = new ArrayList<>();
        try {
            Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
            while (nis.hasMoreElements()) {
                NetworkInterface ni = nis.nextElement();
                if (!isValidInterface(ni)) continue;

                byte[] hwAddr = ni.getHardwareAddress();
                if (hwAddr != null && hwAddr.length > 0) {
                    macs.add(formatMac(hwAddr));
                }
            }
        } catch (SocketException e) {
            log.warn("獲取 MAC 失敗", e);
        }
        return macs;
    }

    /** 校驗網卡有效性:UP、非回環、非虛擬、非點對點 */
    private static boolean isValidInterface(NetworkInterface ni) throws SocketException {
        return ni.isUp()
            && !ni.isLoopback()
            && !ni.isVirtual()
            && !ni.isPointToPoint()
            && !ni.getName().matches(".*(docker|veth|br-|vmnet|vboxnet|tun|tap).*"); // 常見虛擬網卡前綴
    }

    /** 校驗 IPv4:非回環、非鏈路本地、匹配模式 */
    private static boolean isValidIpv4(InetAddress ia) {
        return !ia.isLoopbackAddress()
            && !ia.isLinkLocalAddress()
            && IPV4_PATTERN.matcher(ia.getHostAddress()).matches();
    }

    /** 格式化 MAC:XX-XX-XX-XX-XX-XX 大寫 */
    private static String formatMac(byte[] bytes) {
        StringBuilder sb = new StringBuilder(17);
        for (int i = 0; i < bytes.length; i++) {
            if (i > 0) sb.append('-');
            int v = bytes[i] & 0xFF;
            sb.append(String.format("%02X", v));
        }
        return sb.toString();
    }
}

關鍵設計決策解析

決策點方案理由
IPv4 正則(\\d{1,3}\\.){3}\\d{1,3}快速過濾 IPv6、主機名,避免 InetAddress 解析開銷
虛擬網卡過濾名稱黑名單 + isVirtual()Docker、VMware、VPN 等虛擬介面無業務意義,且 MAC 常全零或隨機
多 IP 策略返回列表,調用方按優先級選(如優先 10.x、172.x、192.168.x)業務場景不同,避免工具類硬編碼優先級
MAC 格式連字符分隔大寫符合多數 CMDB、資產系統錄入規範

跨平台驗證矩陣

OS測試場景結果
Linux (CentOS/Ubuntu)雙網卡綁定、VLAN 子介面、Docker 橋接✅ 正確返回物理網卡 IP/MAC
Windows Server 2019Hyper-V 虛擬交換器、多網卡團隊✅ 過濾虛擬介面,獲取物理網卡
macOS (M1/M2)Wi-Fi + Thunderbolt 以太網✅ 正常
容器 (K8s Pod)hostNetwork=true/false⚠️ hostNetwork=false 只見 Pod 內部介面,需配合 Downward API 獲取宿主信息

容器化環境特殊處理

K8s 中若需宿主機 IP/MAC,推薦:

  1. Downward API:將宿主 IP 注入 Pod 環境變量(需宿主運行 host-local-ip-daemonset)。
  2. Node 擴展標籤:由 Operator 維護節點網卡信息至 Node Label/Annotation。
  3. 側車模式:特權側車容器讀取 /sys/class/net/ 宿主網卡信息。

總結

遍歷 NetworkInterface、多維度過濾(狀態、類型、名稱)、返回集合而非單值,是獲取服務器網絡身份的穩健姿勢。工具類零依賴、易擴展,可直接集成至微服務啟動檢查、分布式鎖節點標識、審計日誌上下文等場景。

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