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

Java 通過 IP 獲取客戶端 MAC 地址:跨平台實現方案

     編輯:Java 程式設計入門

核心原理:ARP 協議與系統命令

MAC 地址屬於數據鏈路層,無法直接跨網段獲取。在局域網內,可利用 ping 觸發 ARP 請求,再通過 arp -a 讀取緩存表解析 MAC。

完整工具類實現

public class MacAddressResolver {

    /** 執行單條命令並返回輸出 */
    private static String execCmd(String[] cmd) {
        StringBuilder output = new StringBuilder();
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(Runtime.getRuntime().exec(cmd).getInputStream()))) {
            String line;
            while ((line = br.readLine()) != null) output.append(line);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return output.toString();
    }

    /** 執行雙命令:先 ping 再 arp */
    private static String execSequentialCmd(String[] pingCmd, String[] arpCmd) {
        try {
            Process pingProc = Runtime.getRuntime().exec(pingCmd);
            pingProc.waitFor(); // 等待 ping 完成,確保 ARP 表已更新
            return execCmd(arpCmd);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /** 從命令輸出中提取指定 IP 對應的 MAC */
    private static String extractMac(String ip, String output, String separator) {
        String regex = "((([0-9A-Fa-f]{1,2}" + separator + "){1,5})[0-9A-Fa-f]{1,2})";
        Matcher matcher = Pattern.compile(regex).matcher(output);
        while (matcher.find()) {
            String mac = matcher.group(1);
            // 確保 MAC 位於該 IP 之後(應對多 IP 場景)
            if (output.indexOf(ip) <= output.lastIndexOf(mac)) return mac;
        }
        return "";
    }

    /** Windows 環境獲取 MAC */
    public static String getMacWindows(String ip) {
        String[] ping = {"cmd", "/c", "ping " + ip};
        String[] arp = {"cmd", "/c", "arp -a"};
        return extractMac(ip, execSequentialCmd(ping, arp), "-");
    }

    /** Linux 環境獲取 MAC */
    public static String getMacLinux(String ip) {
        String[] cmd = {"/bin/sh", "-c", "ping " + ip + " -c 2 && arp -a"};
        return extractMac(ip, execCmd(cmd), ":");
    }

    /** 統一入口:優先嘗試 Windows,失敗再試 Linux */
    public static String getMacAddress(String ip) {
        String mac = getMacWindows(ip).trim();
        return (mac.isEmpty()) ? getMacLinux(ip).trim() : mac;
    }
}

關鍵注意事項

  • 權限要求:Windows 需管理員權限;Linux 需 root 或 cap_net_raw 能力
  • 同網段限制:跨路由器/網關無法獲取真實 MAC,只能得到網關 MAC
  • 超時處理:建議為 ping 設置超時,避免不可達 IP 導致阻塞
  • 現代替代方案:Java 9+ 可用 NetworkInterface.getByInetAddress() 直接查詢本機網卡,無需執行命令

適用場景

內網設備管理、軟件授權綁定、訪問控制白名單等純局域網場景。公網環境請勿依賴此方案。

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