2011-05-28 169 views
20

我可以使用获取MAC地址与Java

ip = InetAddress.getLocalHost(); 
NetworkInterface.getByInetAddress(ip); 

获取MAC地址,但如果我在离线机器使用此代码,这是行不通的。

那么,如何获取Mac地址?

+3

从技术上讲,你应该尽管它有没有网卡反正治疗脱机机。你如何处理后一种情况? – 2011-05-28 20:28:34

+1

为什么你的程序需要这些信息?它为最终用户带来了什么好处? – 2011-05-28 20:58:50

+0

如果机器有多个?你是否知道用户可以更改MAC地址?在Java中,除了尝试将其用作机器标识符之外,您无法使用Java中的MAC地址执行任何操作,但这是不适合的。 – EJP 2011-05-28 23:34:33

回答

26

与Java 6+,你可以使用NetworkInterface.getHardwareAddress

请记住,一台计算机可以没有网卡,特别是如果它是嵌入式或虚拟的。它也可以有多个。您可以通过NetworkInterface.getNetworkInterfaces()获得所有网卡的列表。

+3

我有一个问题,我在某些计算机上只有一个截断的4字节的mac地址。我设法通过包括-Djava.net.preferIPv4Stack = true来解决这个问题。作为java的启动参数 – runholen 2014-12-08 14:52:55

1

另一种方法是通过本机代码执行使用OS命令'getmac'。

Process p = Runtime.getRuntime().exec("getmac /fo csv /nh"); 
    java.io.BufferedReader in = new java.io.BufferedReader(new java.io.InputStreamReader(p.getInputStream())); 
    String line; 
    line = in.readLine();   
    String[] result = line.split(","); 

    System.out.println(result[0].replace('"', ' ').trim()); 
+4

'getmac'仅在Windows上可用。但不是在Ubuntu 13.10(也没有'apt-get')和Android 4.2。 – 2014-04-09 12:12:02

1

试试这个:

final NetworkInterface netInf = NetworkInterface.getNetworkInterfaces().nextElement(); 
final byte[] mac = netInf.getHardwareAddress(); 
final StringBuilder sb = new StringBuilder(); 
for (int i = 0; i < mac.length; i++) { 
     sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));   
} 
log.info("Mac addr: {}", sb.toString()); 
+0

有些例外,你应该赶上。 – 2015-03-31 12:46:03

0

here荡涤代码:

import java.net.InetAddress; 
import java.net.NetworkInterface; 
import java.net.SocketException; 
import java.net.UnknownHostException; 

public class HardwareAddress 
{ 
    public static String getMacAddress() throws UnknownHostException, 
      SocketException 
    { 
     InetAddress ipAddress = InetAddress.getLocalHost(); 
     NetworkInterface networkInterface = NetworkInterface 
       .getByInetAddress(ipAddress); 
     byte[] macAddressBytes = networkInterface.getHardwareAddress(); 
     StringBuilder macAddressBuilder = new StringBuilder(); 

     for (int macAddressByteIndex = 0; macAddressByteIndex < macAddressBytes.length; macAddressByteIndex++) 
     { 
      String macAddressHexByte = String.format("%02X", 
        macAddressBytes[macAddressByteIndex]); 
      macAddressBuilder.append(macAddressHexByte); 

      if (macAddressByteIndex != macAddressBytes.length - 1) 
      { 
       macAddressBuilder.append(":"); 
      } 
     } 

     return macAddressBuilder.toString(); 
    } 
} 
16

尽管我已经在这里找到了可行的解决方案和另一个答复,然后我将与贡献我的解决方案您需要使用包含“ip”或“mac”的字符串指定参数,具体取决于您需要检查的内容。如果计算机没有接口,那么它将返回一个包含null的字符串,否则将返回一个包含你请求的字符串(IP地址或MAC)的字符串。

如何使用它:

System.out.println("Ip: " + GetNetworkAddress.GetAddress("ip")); 
System.out.println("Mac: " + GetNetworkAddress.GetAddress("mac")); 

结果(如果计算机有一个网卡):

Ip: 192.168.0.10 
Mac: 0D-73-ED-0A-27-44 

结果(如果电脑没有网卡):

Ip: null 
Mac: null 

这里是代码:

import java.net.Inet4Address; 
import java.net.InetAddress; 
import java.net.NetworkInterface; 
import java.net.SocketException; 
import java.net.UnknownHostException; 
import java.util.Enumeration; 

public class GetNetworkAddress { 

    public static String GetAddress(String addressType) { 
     String address = ""; 
     InetAddress lanIp = null; 
     try { 

      String ipAddress = null; 
      Enumeration<NetworkInterface> net = null; 
      net = NetworkInterface.getNetworkInterfaces(); 

      while (net.hasMoreElements()) { 
       NetworkInterface element = net.nextElement(); 
       Enumeration<InetAddress> addresses = element.getInetAddresses(); 

       while (addresses.hasMoreElements() && element.getHardwareAddress().length > 0 && !isVMMac(element.getHardwareAddress())) { 
        InetAddress ip = addresses.nextElement(); 
        if (ip instanceof Inet4Address) { 

         if (ip.isSiteLocalAddress()) { 
          ipAddress = ip.getHostAddress(); 
          lanIp = InetAddress.getByName(ipAddress); 
         } 

        } 

       } 
      } 

      if (lanIp == null) 
       return null; 

      if (addressType.equals("ip")) { 

       address = lanIp.toString().replaceAll("^/+", ""); 

      } else if (addressType.equals("mac")) { 

       address = getMacAddress(lanIp); 

      } else { 

       throw new Exception("Specify \"ip\" or \"mac\""); 

      } 

     } catch (UnknownHostException ex) { 

      ex.printStackTrace(); 

     } catch (SocketException ex) { 

      ex.printStackTrace(); 

     } catch (Exception ex) { 

      ex.printStackTrace(); 

     } 

     return address; 

    } 

    private static String getMacAddress(InetAddress ip) { 
     String address = null; 
     try { 

      NetworkInterface network = NetworkInterface.getByInetAddress(ip); 
      byte[] mac = network.getHardwareAddress(); 

      StringBuilder sb = new StringBuilder(); 
      for (int i = 0; i < mac.length; i++) { 
       sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : "")); 
      } 
      address = sb.toString(); 

     } catch (SocketException ex) { 

      ex.printStackTrace(); 

     } 

     return address; 
    } 

    private static boolean isVMMac(byte[] mac) { 
     if(null == mac) return false; 
     byte invalidMacs[][] = { 
       {0x00, 0x05, 0x69},    //VMWare 
       {0x00, 0x1C, 0x14},    //VMWare 
       {0x00, 0x0C, 0x29},    //VMWare 
       {0x00, 0x50, 0x56},    //VMWare 
       {0x08, 0x00, 0x27},    //Virtualbox 
       {0x0A, 0x00, 0x27},    //Virtualbox 
       {0x00, 0x03, (byte)0xFF},  //Virtual-PC 
       {0x00, 0x15, 0x5D}    //Hyper-V 
     }; 

     for (byte[] invalid: invalidMacs){ 
      if (invalid[0] == mac[0] && invalid[1] == mac[1] && invalid[2] == mac[2]) return true; 
     } 

     return false; 
    } 

} 

更新02/05/2017:感谢@mateuscb发布的帖子How to Determine Internet Network Interface in Java,很遗憾之前没有得到任何upvote,但他为这个更新做出了贡献。

的方法进行了改进,以跳过虚拟机网卡(最流行的VM软件)

+0

如果在if(invalid [0] == mac [0] && invalid [1] == mac [1] && invalid [2] == mac [2])给出一个'ArrayIndexOutOfBounds'异常,我该怎么办?返回true;'? – Sumit 2017-09-27 10:55:00

+0

@Sumit检查两个数组“无效”和“mac”中的项目数,因为其中一个或两者都少于三个项目 – 2017-09-27 11:11:50

+0

因此,我在https://stackoverflow.com/a/找到另一段代码16449379/3169868,其中第一个MAC地址显示为空白,剩余3个(包括虚拟机)。可以修改这个代码来处理这个问题吗? – Sumit 2017-09-27 11:17:06