Java: 获取MAC网络地址
Java: 获取MAC网络地址
0. 背景
最近由于课程设计,需要使用MAC物理地址作为软件***的唯一标识,故成此博客!
从各个网络适配器的作用 确定哪一个MAC地址作为唯一标识。在此记录,与诸君分享。
1. 首先打开cmd ipconfig/all
,查看所有MAC地址:
2. 博主的ipconfig存在8个网络适配器,故而存在 8 个MAC物理地址。
其中每个网络适配器的含义如下:
Mac网卡地址解析:
-
Sangfor SSL VPN CS Support System VNIC
EasyConnect,远程连接VPN应用产生的虚拟网卡。
具备Mac网卡地址
-
Realtek PCIe GBE Family Controller
realtek公司生产的PCIe接口的千兆以太网家用控制器,即 有线网卡。
具备Mac网卡地址
-
VirtualBox Host-Only Ethernet Adapter
用于对 虚拟机 进行 通信 的适配器。
具备Mac网卡地址
-
Npcap Loopback Adapter
虚拟网卡,不涉及硬件,它被用于在网络连接不可用时,作为测试虚拟网络环境的工具。
此外,如果 网络适配器(network adapter) / 网络适配器驱动程序(network adapter driver) 发生冲突,则必须使用 Loopback适配器。
Java中的NetworkInterface中定义:
loopback interface that only supports communication between entities on this machine.
本地环回测试的MAC地址,全球所有的计算机相同!!!
具备Mac网卡地址
-
Microsoft Wi-Fi Direct Virtual Adapter
虚拟网卡,使用PC的便携式 热点(hotspot) 共享PC的互联网连接。
当PC连接无线网,并开启移动热点后,PC会向外发射信号给其他终端,其他终端检测到PC发射出的网络信号,并且可以连接PC发出的无线网络!
多用于移动设备投屏PC。
具备Mac网卡地址
-
Microsoft Wi-Fi Direct Virtual Adapter #2
Virual Wi-Fi是一种虚拟化网络适配器的技术,一旦被虚拟化,那么,即可将 1 个物理无线适配器转换为 2 个虚拟适配器。
具备Mac网卡地址
-
Intel® Dual Band Wireless-AC 3168
无线网卡。
具备Mac网卡地址
-
Bluetooth Device (Personal Area Network)
一种允许创建一个以太网(Ethernet network) 的技术,其允许计算机与移动设备等进行连接。
局域网(PAN)网卡。
具备Mac网卡地址
3. 了解了各网络适配器的MAC物理地址后,我们可以更加 自信 的编程了!
因为MAC地址数量很多,而虚拟网卡的MAC地址又可以后期修改,只有 无线网卡(Intel® Dual Band Wireless-AC 3168) 和 有限网卡(Realtek PCIe GBE Family Controller) 的MAC物理地址始终无法被改变并且绝大多数电脑都具备这两种网卡;
故,此处选择 无线网卡(Intel® Dual Band Wireless-AC 3168) 的MAC地址作为软件***的唯一标识。
ps:这里说明下,为什么不选择 Npcap Loopback Adapter 的MAC地址作为唯一标识的原因:
因为,全球所有的计算机的 Loopback Adapter 的 MAC地址 都为 02-00-4C-4F-4F-50
;
而且,因为 MAC地址 位于计算机网络OSI参考模型的 数据链路层 中,其 作用 是 在网络中唯一标示一个网卡,并由此标识唯一计算机,这样,该计算机才能准确的与其他计算机通信
;
然而, Loopback 的 作用 是用于 本地环回测试
,不需要与其他计算机通信,因此其物理地址全球性一致,不具有唯一标识性。
ps: 感兴趣的小朋友可以cmd ipconfig/all
看下,是不是你的 Loopback 的MAC地址 是否与博主一致!????
获取MAC地址程序如下:
import sun.encryption.constants.Constants;
import sun.encryption.domain.Network;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.List;
import java.util.Enumeration;
public class NetworkUtil {
/**
* 一台机器可能存在多个网卡, 故返回数组
* 网络接口地址(NetworkInterface) ----> 接口地址(InterfaceAddress) ----> IP地址(InetAddress)
* ----> 网络接口地址(NetworkInterface)
* @return
* @throws Exception
*/
public static List<Network> getMacAddresses() throws Exception {
// 获取机器上的所有网络接口, 返回结果至少包含一项(即, loopback本地环回测试)
// getNetworkInterfaces() + getInetAddresses()可以获取到所有IP地址
Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
StringBuilder sb = new StringBuilder();
ArrayList<String> networkNames = new ArrayList<String>();
// 保存mac地址列表
ArrayList<Network> macList = new ArrayList<Network>();
// 使用标签, 跳出多重循环
here:
while (en.hasMoreElements()) {
NetworkInterface iface = en.nextElement();
// 获取对应网络接口的所有接口地址(InterfaceAddress)
List<InterfaceAddress> addrs = iface.getInterfaceAddresses();
for (InterfaceAddress addr : addrs) {
// InetAddress: Internet Protocol (IP) address: IP地址
// 返回网络接口地址对应的IP地址
InetAddress ip = addr.getAddress();
// 由IP地址获取网络接口(NetworkInterface)
// 方便方法搜索到绑定到其的具体IP地址的网络接口(NetworkInterface)
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(ip);
// 若为空, 跳过
if (networkInterface == null) {
continue;
}
// 获取以太网等名称, 如:eth0, eth1, wlan1
String name = networkInterface.getName();
// 获取描述
String displayName = networkInterface.getDisplayName();
// 当网络接口有权限连接, 并且其具有MAC地址时, 返回二进制MAC硬件地址
byte[] mac = networkInterface.getHardwareAddress();
// 是否为虚拟网络接口
boolean virtual = networkInterface.isVirtual();
// 网络接口是否启动
boolean up = networkInterface.isUp();
if (mac == null) {
continue;
}
// 清空StringBuffer中的内容
sb.delete(0, sb.length());
// 转换MAC地址格式
for (int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
}
Network network = new Network();
// 若网络接口首次出现, 避免返回结果重复
if (!networkNames.contains(name)) {
networkNames.add(name);
network.setName(name);
network.setDisplayName(displayName);
network.setMac(sb.toString());
network.setVirtual(virtual);
network.setUp(up);
macList.add(network);
}
// 若找到, 跳出
if (networkNames.contains(Constants.WIRELESS)) {
break here;
}
}
}
return macList;
}
// 根据字符串"wireless"找到对应mac地址
// 方法有效的条件是: PC机具有无线网卡
// linux再议
public static String getWirelessMacAddress() throws Exception {
List<Network> macs = getMacAddresses();
for (Network mac: macs) {
if (mac.getDisplayName().toLowerCase().contains(Constants.WIRELESS)) {
return mac.getMac();
}
}
return null;
}
public static void main(String[] args) throws Exception {
String wirelessMac = getWirelessMacAddress();
System.out.println(wirelessMac);
}
}
上一篇: 以太坊中GraphQL简介及使用