java如何获取mac物理地址

前言

原本以为这功能调用一个api就完事了,然而,查了一下没那么简单,网上查的资料实在忍不住要拿出来说说,估计真的都没有试过其他环境,而且,估计连背后的原理都没了解就用了。。
下面先说说找到的几份资料:

ps:本机相关ip信息:
在这里插入图片描述

第一篇参考

Java获取本机MAC地址

点评:实际运行效果如下:
在这里插入图片描述
空指针啊。。。那么我们如果换个ip来试试?

第二篇参考

使用java获取本机mac

看看代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class getmac{
public static String getLinuxMACAddress() {
String mac = null;
BufferedReader bufferedReader = null;
Process process = null;
try {
process = Runtime.getRuntime().exec(“ifconfig enp4s0”);
bufferedReader = new BufferedReader(new InputStreamReader(
process.getInputStream()));
String line = null;
int index = -1;
while ((line = bufferedReader.readLine()) != null) {
index = line.toLowerCase().indexOf(“硬件地址”);

            if (index != -1) {
                
                mac = line.substring(index + 4).trim();
                break;
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (bufferedReader != null) {
                bufferedReader.close();
            }
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        bufferedReader = null;
        process = null;
    }
    return mac;
}

public static void main(String[] argc) {
String mac = getLinuxMACAddress();
System.out.println(“本地是Linux系统, MAC地址是:” + mac);

}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

一运行:
在这里插入图片描述

还是不行。。里面几行代码我有点在意:

process = Runtime.getRuntime().exec("ifconfig enp4s0");

index = line.toLowerCase().indexOf(“硬件地址”);

  • 1
  • 2
  • 3
  • 4
  • 5

调用命令ifconfig enp4s0 然后根据字符串“硬件地址”来截取字符,获得mac地址

这样做估计不行,部署到正式环境分分钟挂掉机器

首先:
不同机器的enp这些东西是不一样的:
在这里插入图片描述
其次,“硬件地址”这个字符串估计在不同机器上面有不同的解释吧。。。

第三份资料

How can i get list of MAC address and IP address of computer through java?

为了方便查看,我抄一下【墙的强度略大,google的js脚本都卡掉了,估计大家都是卡五六分钟才看到的,我懂】

在这里插入图片描述

在这里插入图片描述

两段代码如下:

           InetAddress ip;
    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());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

                    java.util.Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
        en.hasMoreElements(); ) {
        NetworkInterface iface = en.nextElement();
        List<InterfaceAddress> addrs = iface.getInterfaceAddresses();
        //For each network interfaces iterate through each ip address
        for(InterfaceAddress addr : addrs) {
                         ip = addr.getAddress();
                          //Process the IP ...

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

好了,根据以上回答及代码,补充完整,然后查看结果

单地址:

package test;

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

public class SingleNetAddress {
/*
* @param args
* @throws UnknownHostException
* @throws SocketException
*/
public static void main(String[] args) throws UnknownHostException, SocketException {

    System.out.println("进行single net address 测试===》");

    InetAddress ip;
    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 &lt; mac.length; i++) {
        sb.append(String.format("%02X%s", mac[i], (i &lt; mac.length - 1) ? "-" : ""));
    }
    System.out.println(sb.toString());

}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

运行结果:

在这里插入图片描述

不行,还是出错了。。

多地址的:

package test;

import java.net.*;
import java.util.List;

public class MultiNetAddress {
/*
* @param args
* @throws UnknownHostException
* @throws SocketException
*/
public static void main(String[] args) throws UnknownHostException, SocketException {
System.out.println(“进行 multi net address 测试===》”);
java.util.Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
while(en.hasMoreElements()){
NetworkInterface iface = en.nextElement();
List<InterfaceAddress> addrs = iface.getInterfaceAddresses();
//For each network interfaces iterate through each ip address
//For each network interfaces iterate through each ip address
for(InterfaceAddress addr : addrs) {
InetAddress ip = addr.getAddress();
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 &lt; mac.length; i++) {
                sb.append(String.format("%02X%s", mac[i], (i &lt; mac.length - 1) ? "-" : ""));
            }
            System.out.println(sb.toString());
        }
    }


}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

运行结果:
在这里插入图片描述

欸,有点意思了,已经接近需要的结果了,看看之前本机的ifconfig的值:
在这里插入图片描述
起码蒙对了一个,不过enp3s0的还是没读出来。突破口就在这里。

下面查一查ifconfig下面的各个含义是什么。。我到现在都不明白这些含义,估计一天不弄清楚一天都没办法获得真正的物理地址了。
Linux网卡命名enp3s0说明
在这里插入图片描述

还有一篇:
linux下eth0 lo wlan0

在这里插入图片描述
在这里插入图片描述
通过阅读可以理解到,ifconfig在每个系统出来的名称还有格式估计都是有差别的。用字符串识别提取方式来获得mac地址估计。。。真的不行。mac地址在linux下面也是可以修改的。

而且:
en eth 都是本地网卡,有mac地址
lo是localhost,本机地址—这个不属于网卡吧,没有mac地址的吧?
wlan wl意思是无线网卡,也有mac地址。

我的是手提电脑,当然有无线网卡也有本地网卡。。额,这样就解释了:

enp3s0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether d8:c4:97:43:41:2f  txqueuelen 1000  (以太网)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (本地环回)
RX packets 4067 bytes 537739 (537.7 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4067 bytes 537739 (537.7 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

wlp5s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.102 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::136b:f8d9:d35:b59 prefixlen 64 scopeid 0x20<link>
ether 68:ec:c5:c4:d1:96 txqueuelen 1000 (以太网)
RX packets 107772 bytes 149800655 (149.8 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 26297 bytes 4348455 (4.3 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

wlp5s0 无线网卡 有ip地址,ipv4: inet 192.168.0.102 ipv6: inet6 fe80::136b:f8d9:d35:b59 mac地址:68:ec:c5:c4:d1:96

而 enp3s0 内置网卡没有 ipv4,也没有ipv6地址,mac地址:d8:c4:97:43:41:2f

因为没有接网线啊,接的是无线。

lo 没有mac地址,ipv4为:127.0.0.1 ipv6为: ::1

网线网卡测试

为了求证上面结论,那么下面来做基本的试验,

笔记本用无线上网,没有插入网线

在这里插入图片描述

笔记本用禁用无线上网,插入网线

在这里插入图片描述

欸,wl不见了,en有ip地址了。。

笔记本用启用无线上网,插入网线

在这里插入图片描述
en,wl同时存在,都有ip地址。

而lo一直没有mac地址,ip地址一直是本地。就是说,java 获取本机ipmac时候,获取到本机lo的地址然后肯定没办法获得mac地址咯?

其他电脑ifconfig的表现

为了验证lo是不是不会有mac地址,特意查看其他人其他机器的表现,如下:
linux命令之ifconfig详细解释

在这里插入图片描述

估计lo真的是不会有mac地址了。。共性。所以现在的问题在于,如何遍历获取多个网卡的mac地址?

优化获取代码,不同情况进行试验

好了,现在来优化一下代码,在不同情况下运行程序进行测试:

代码如下:

package test;

import java.net.*;
import java.util.List;

public class MultiNetAddress {
/*
* @param args
* @throws UnknownHostException
* @throws SocketException
*/
public static void main(String[] args) throws UnknownHostException, SocketException {
System.out.println(“进行 multi net address 测试===》”);
java.util.Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
while(en.hasMoreElements()){
NetworkInterface iface = en.nextElement();
List<InterfaceAddress> addrs = iface.getInterfaceAddresses();
//For each network interfaces iterate through each ip address
//For each network interfaces iterate through each ip address
for(InterfaceAddress addr : addrs) {
InetAddress ip = addr.getAddress();
System.out.println("Current IP address : " + ip.getHostAddress());

            NetworkInterface network = NetworkInterface.getByInetAddress(ip);

            if(network==null){
                System.out.println("真遗憾,系统无法获取"+ip+" 的network对象!!");
            }
            else{
                byte[] mac = network.getHardwareAddress();

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

                StringBuilder sb = new StringBuilder();
                if(mac==null)
                {
                    System.out.println("真遗憾,系统无法获取"+ip+" 的mac地址");
                }
                else{
                    for (int i = 0; i &lt; mac.length; i++) {
                        sb.append(String.format("%02X%s", mac[i], (i &lt; mac.length - 1) ? "-" : ""));
                    }
                    System.out.println(sb.toString());
                }
            }

        }
    }


}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

情况一、不接网线,开启连接无线网络

ifconfig结果:
在这里插入图片描述

程序运行结果:
在这里插入图片描述

第二种情况,连接网线,开启并连接无线

ifconfig结果:
在这里插入图片描述

程序运行结果

在这里插入图片描述

第三种情况,连接网线,关闭无线

ifconfig结果

在这里插入图片描述

运行情况:

在这里插入图片描述

第四种情况,拔出网线,关闭无线

ifconfig结果:
在这里插入图片描述
运行结果:
在这里插入图片描述

获取mac地址的结论

在这几种情况下面

getNetworkInterfaces

 
 
  • 1

返回的分别的肯定有,lo—即localhost连接,
如果eth–内置网卡—有连接网线的话,那么就会包括etch,
如果wlan–无线—有连接的话,那么也会包括wlan。

getInterfaceAddresses

 
 
  • 1

会返回ipv4,以及ipv6的地址,对于lo这个networkinterface来说,会返回:
ipv6 0:0:0:0:0:0:0:1%lo 以及ipv4 127.0.0.1,遗憾的是:
lo的ipv6永远是连接不上的,network是null,而ipv4连接上了也是没有mac地址的,
基本上来说,linux下面是不能通过lo来获取mac的,windows下面不清楚
在这里插入图片描述

而其他两个,只要连接上了—eth以及wlan,只要连接上了就能获得mac地址:

Current IP address : fe80:0:0:0:136b:f8d9:d35:b59%wlp5s0
Current MAC address : 68-EC-C5-C4-D1-96
Current IP address : 192.168.0.102
Current MAC address : 68-EC-C5-C4-D1-96
Current IP address : fe80:0:0:0:d029:29c1:936c:64c9%enp3s0
Current MAC address : D8-C4-97-43-41-2F
Current IP address : 192.168.0.101
Current MAC address : D8-C4-97-43-41-2F

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

无论是ipv4还是ipv6

所以,现在心里面应该有底了,那就是,如何获取mac地址?

mac地址的获取通用代码

package test;

import java.net.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

public class MacTools {
/因为一台机器不一定只有一个网卡呀,所以返回的是数组是很合理的/
public static List<String> getMacList() throws Exception {
java.util.Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
StringBuilder sb = new StringBuilder();
ArrayList<String> tmpMacList=new ArrayList<>();
while(en.hasMoreElements()){
NetworkInterface iface = en.nextElement();
List<InterfaceAddress> addrs = iface.getInterfaceAddresses();
for(InterfaceAddress addr : addrs) {
InetAddress ip = addr.getAddress();
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
if(networknull){continue;}
byte[] mac = network.getHardwareAddress();
if(mac
null){continue;}
sb.delete( 0, sb.length() );
for (int i = 0; i < mac.length; i++) {sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? “-” : “”));}
tmpMacList.add(sb.toString());
} }
if(tmpMacList.size()<=0){return tmpMacList;}
/去重,别忘了同一个网卡的ipv4,ipv6得到的mac都是一样的,肯定有重复,下面这段代码是。。流式处理/
List<String> unique = tmpMacList.stream().distinct().collect(Collectors.toList());
return unique;
}
public static void main(String[] args) throws Exception {
System.out.println(“进行 multi net address 测试===》”);
List<String> macs=getMacList();
System.out.println(“本机的mac网卡的地址有:”+macs);

}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

运行结果:
在这里插入图片描述

后语

话说,真自豪。能够有理有据,各个情况都有考虑,将mac地址的获取清楚说出来的,恐怕不多。很多都是开局一段码,结果全靠蒙。
希望上面的东西能够帮到你、

                                </div>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值