简体   繁体   English

使用Java获取本地机器上的MAC地址

[英]Get MAC address on local machine with Java

I can use我可以用

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

to obtain the mac address, but if I use this code in an offline machine it doesn't work.获取 mac 地址,但如果我在离线机器上使用此代码,则它不起作用。

So, How can I get the Mac address?那么,如何获取Mac地址呢?

With Java 6+, you can use NetworkInterface.getHardwareAddress .对于 Java 6+,您可以使用NetworkInterface.getHardwareAddress

Bear in mind that a computer can have no network cards, especially if it's embedded or virtual.请记住,计算机可以没有网卡,特别是如果它是嵌入式的或虚拟的。 It can also have more than one.它也可以有多个。 You can get a list of all network cards with NetworkInterface.getNetworkInterfaces() .您可以使用NetworkInterface.getNetworkInterfaces()获取所有网卡的列表。

With all the possible solutions that i've found here and another replies, then i will contribute with my solution.有了我在这里找到的所有可能的解决方案和其他答复,然后我将提供我的解决方案。 You need to specify a parameter with a String containing "ip" or "mac" depending on what you need to check.您需要使用包含“ip”或“mac”的字符串指定参数,具体取决于您需要检查的内容。 If the computer has no interface, then it will return an String containing null, otherwise will return a String containing what you asked for (the ip address or the mac).如果计算机没有接口,那么它将返回一个包含 null 的字符串,否则将返回一个包含您所要求的字符串(ip 地址或 mac)。

How to use it:如何使用它:

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

Result (if the computer has a network card):结果(如果电脑有网卡):

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

Result (if the computer doesn't have a network card):结果(如果电脑没有网卡):

Ip: null
Mac: null

Here's the code:这是代码:

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;
    }

}

UPDATED 02/05/2017: Thanks to @mateuscb on the post How to Determine Internet Network Interface in Java that unfortunately didn't get any upvote on that post before, but he contributed to this update. 2017 年 2 月 5 日更新:感谢@mateuscb 在如何确定 Java中的Internet 网络接口一文中,不幸的是,该帖子之前没有得到任何赞成,但他为本次更新做出了贡献。

The method has been improved to skip virtual machine network cards (most popular VM software)改进了跳过虚拟机网卡的方法(最流行的VM软件)

As for the computer being offline, it usually doesn't have an IP assigned, because DHCP is widely used...至于离线的电脑,通常是没有分配IP的,因为DHCP被广泛使用...

And for the question in the title: NetworkInterface.getHardwareAddress()对于标题中的问题: NetworkInterface.getHardwareAddress()

Try this:试试这个:

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());

Another way is to use an OS command 'getmac' through native code execution.另一种方法是通过本机代码执行使用操作系统命令“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());

Cleaned up code from 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();
    }
}

@Jesus Flores, still not working for me, this code: @Jesus Flores,仍然没有为我工作,这段代码:

element.getHardwareAddress().length > 0 

is throwing exception. 抛出异常。 We have to check for null. 我们必须检查是否为null。 Final solution in your case that is working for me: 您案例中的最终解决方案对我有用:

            while (addresses.hasMoreElements()
                    && element.getHardwareAddress() != null
                    && element.getHardwareAddress().length > 0
                    && !isVMMac(element.getHardwareAddress())) {
                final InetAddress ip = addresses.nextElement();
                if (ip instanceof Inet4Address) {
                    // || ip instanceof Inet6Address
                    if (ip.isSiteLocalAddress()) {
                        ipAddress = ip.getHostAddress();
                        lanIp = InetAddress.getByName(ipAddress);
                    }
                }
            }

I am working always over wi-fi. 我一直在做无线网络。

Medium access control address ( MAC address )媒体访问控制地址( MAC地址

MAC address of a device is a unique identifier assigned to a network interface controller (NIC).设备的 MAC 地址是分配给网络接口控制器 (NIC) 的唯一标识符。 For communications within a network segment, it is used as a network address for most IEEE 802 network technologies, including Ethernet, Wi-Fi, and Bluetooth.对于网段内的通信,它用作大多数 IEEE 802 网络技术的网络地址,包括以太网、Wi-Fi 和蓝牙。 Within the Open Systems Interconnection ( OSI ) model, MAC addresses are used in the medium access control protocol sublayer of the data link layer.在开放系统互连 ( OSI ) 模型中,MAC 地址用于数据链路层的媒体访问控制协议子层。

MAC addresses are most often assigned by the manufacturer of network interface cards. MAC 地址通常由网络接口​​卡制造商分配。 Each is stored in hardware, such as the card's read-only memory or by a firmware mechanism.每个都存储在硬件中,例如卡的只读存储器或通过固件机制。

Use the following function getPhysicalAddress() to get list of MAC address:使用以下函数getPhysicalAddress()获取 MAC 地址列表:

static String format = "%02X"; // To get 2 char output.
private static String[] getPhysicalAddress() throws Exception{
    try {
        // DHCP Enabled - InterfaceMetric
        Set<String> macs = new LinkedHashSet<String>();

        Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
        while( nis.hasMoreElements() ) {
            NetworkInterface ni = nis.nextElement();
            byte mac [] = ni.getHardwareAddress(); // Physical Address (MAC - Medium Access Control)
            if( mac != null ) {
                final StringBuilder macAddress = new StringBuilder();
                for (int i = 0; i < mac.length; i++) {
                    macAddress.append(String.format("%s"+format, (i == 0) ? "" : ":", mac[i]) );
                    //macAddress.append(String.format(format+"%s", mac[i], (i < mac.length - 1) ? ":" : ""));
                }
                System.out.println(macAddress.toString());
                macs.add( macAddress.toString() );
            }
        }
        return macs.toArray( new String[0] );
    } catch( Exception ex ) {
        System.err.println( "Exception:: " + ex.getMessage() );
        ex.printStackTrace();
    }
    return new String[0];
}
public static void main(String[] args) throws Exception {
    InetAddress localHost = InetAddress.getLocalHost();
    System.out.println("Host/System Name : "+ localHost.getHostName());
    System.out.println("Host IP Address  : "+ localHost.getHostAddress());

    String macs2 [] = getPhysicalAddress();
    for( String mac : macs2 )
        System.err.println( "MacAddresses = " + mac );
}

The above function works as ipconfig /all|find "Physical Address" >>MV-mac.txt .上述函数作为ipconfig /all|find "Physical Address" >>MV-mac.txt

D:\>ipconfig /all|find "Physical Address"
   Physical Address. . . . . . . . . : 94-57-A6-00-0C-BB
   Physical Address. . . . . . . . . : 01-FF-60-93-0B-88
   Physical Address. . . . . . . . . : 62-B8-9A-2B-F3-87
   Physical Address. . . . . . . . . : 60-B8-9A-2B-F3-87
   Physical Address. . . . . . . . . : 60-B8-9A-2B-F3-87

The IEEE divides the OSI data link layer into two separate sublayers: IEEE 将 OSI 数据链路层分为两个独立的子层:

  • Logical link control (LLC): Transitions up to the network layer逻辑链路控制 (LLC):过渡到网络层
  • MAC: Transitions down to the physical layer Image ref MAC:向下过渡到物理层Image ref

getmac 获取麦克

Returns the media access control (MAC) address and list of network protocols associated with each address for all network cards in each computer, either locally or across a network.返回媒体访问控制 (MAC) 地址和与每台计算机中所有网卡的每个地址关联的网络协议列表,无论是本地还是跨网络。

D:\>getmac /fo csv /nh

NET START command 网络启动命令

D:\>netsh interface ipv4 show addresses

Kotlin:科特林:

NetworkInterface.getNetworkInterfaces()
    .asSequence()
    .mapNotNull { ni ->
        ni.hardwareAddress?.joinToString(separator = "-") {
            "%02X".format(it)
        }
    }.toList()
public static void main(String[] args){

        InetAddress ip;
        try {

            ip = InetAddress.getLocalHost();
            System.out.println("Current IP address : " + ip.getHostAddress());

            NetworkInterface network = NetworkInterface.getByInetAddress(ip);

            byte[] mac = network.getHardwareAddress();

            System.out.print("Current MAC address : ");

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

        } catch (Exception e) {

            e.printStackTrace();

        }

       }

output:输出:

Current IP address : 192.168.21.60
Current MAC address : 70-5A-0F-3C-84-F2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM