开发一个自动检测网卡的MAC地址及与其绑定的IP地址的工具。
开发一个自动检测网卡的MAC地址及与其绑定的IP地址的工具。
基础概念介绍:
网卡:网卡是一块被设计用来允许计算机在计算机网络上进行通讯的计算机硬件。由于其拥有MAC地址,因此属于OSI模型的第2层。它使得用户可以通过电缆或无线相互连接。每一个网卡都有一个被称为MAC地址的独一无二的串行号,它被写在卡上的一块ROM中。在网络上的每一个计算机都必须拥有一个独一无二的MAC地址。
MAC地址:MAC地址就是在媒体接入层上使用的地址,也叫物理地址、硬件地址或链路地址,由网络设备制造商生产时写在硬件内部。MAC地址与网络无关,也即无论将带有这个地址的硬件接入到网络的何处,都有相同的MAC地址,它由厂商写在网卡的BIOS里。MAC地址通常表示为12个16进制数,每2个16进制数之间用冒号隔开,如:08:00:20:0A:8C:6D就是一个MAC地址,其中前6位16进制数08:00:20代表网络硬件制造商的编号,它由IEEE分配,而后6位16进制数0A:8C:6D代表该制造商所制造的某个网络产品(如网卡)的系列号。每个网络制造商必须确保它所制造的每个以太网设备都具有相同的前三字节以及不同的后三个字节。这样就可保证世界上每个以太网设备都具有唯一的MAC 地址。
IP地址:IP地址是指互联网协议地址,它是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。
实现思路:
首先使用Java提供的InetAddress类创建对象,通过对象调用getHostName()方法获取本机上 IP 地址的主机名,再通过对象调用getHostAddress()方法以文本表现形式获取 IP 地址字符串。
核心代码如下:`
InetAddress ia = null;
String localname = null;
String localip = null;
String realcam = null;
try {
ia = ia.getLocalHost();
localname = ia.getHostName();
localip = ia.getHostAddress();
//System.out.println("本机名称是:" + localname);
//System.out.println("本机的ip是 :" + localip);
接着使用InetAddress类的getLocalHost()方法获取本地IP对象,并从该对象获取绑定的MAC地址。
核心代码如下:
InetAddress ia1 = InetAddress.getLocalHost();// 获取本地IP对象,从该对象获取绑定的mac地址
具体的获取MAC地址方法getMACAddress(),通过Java提供的NetworkInterface.getByInetAddress(ia).getHardwareAddress()获得本机网卡信息,并得到MAC地址,在经过数据格式化等操作,最终得到正规的MAC地址。
核心代码如下:
// 获得网络接口对象(即网卡),并得到mac地址,mac地址存在于一个byte数组中。
byte[] mac = NetworkInterface.getByInetAddress(ia1).getHardwareAddress();
// 下面代码是把mac地址拼装成String
StringBuffer sb = new StringBuffer();
for (int i = 0; i < mac.length; i++) {
if (i != 0) {
sb.append("-");
}
// mac[i] & 0xFF 是为了把byte转化为正整数
String s = Integer.toHexString(mac[i] & 0xFF);
// System.out.println("--------------");
// System.err.println(s);
sb.append(s.length() == 1 ? 0 + s : s);
}
// 把字符串所有小写字母改为大写成为正规的mac地址并返回
realcam = sb.toString().toUpperCase();
最后使用NetworkInterface.getNetworkInterfaces()获取本机MAC网卡的所有地址,保存在一个数组中。
核心代码如下:
/***因为一台机器不一定只有一个网卡呀,所以返回的是数组是很合理的***/
public static 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 (network == null) {
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 String.join(",",tmpMacList);
}
/***去重,别忘了同一个网卡的ipv4,ipv6得到的mac都是一样的,肯定有重复,下面这段代码是。。流式处理***/
List<String> unique = tmpMacList.stream().distinct().collect(Collectors.toList());
String join = String.join(",", unique);
return join;
}
结果如下图:
完整代码:
import java.net.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class Lis{
@SuppressWarnings("static-access")
public static void main(String[] args) throws Exception {
NewFrame frame1 = new NewFrame();
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//一定要设置关bai闭
frame1.setVisible(true);
//mystart();
}
}
class NewFrame extends JFrame{
private JButton button1;
private JTextArea text1;
public NewFrame(){
super();
this.setSize(500,400);
this.getContentPane().setLayout(null);
this.add(this.getTextArea(),null);
this.add(this.getButton(),null);
this.setTitle("Mac");
}
private JTextArea getTextArea(){
if(text1==null){
text1 = new JTextArea();
text1.setBounds(10,10,300,300);
}
return text1;
}
private JButton getButton(){
if(button1==null){
button1 = new JButton();
button1.setBounds(350,150,71,27);
button1.setText("检测");
button1.addActionListener(new HelloButton());//添加监听du器zhi类,其主dao要的响应都由监听器类的方法实现
//button1.addActionListener();//添加监听du器zhi类,其主dao要的响应都由监听器类的方法实现
}
return button1;
}
String s=mystart();
//String s2=getMACAddress();
private class HelloButton implements ActionListener{
public void actionPerformed(ActionEvent e){
//text1.append(s2);
text1.append(s);
}
}
private static String mystart() {
String total="";
try {
long a = System.currentTimeMillis();
String macs = getMacList();
String macs1 = macs.replace(",","\n");
System.out.println(macs1);
long b = System.currentTimeMillis();
total=getMACAddress()+"\n本机的mac网卡的所有地址有:\n"+macs1+"\n\n"+"总耗时----" + (b - a) + "-----ms"+"\n";
} catch (Exception e) {
e.printStackTrace();
}
return total;
}
// 获取绑定MAC地址和本机ip的方法
private static String getMACAddress() {
// StringBuffer buf=new StringBuffer();
InetAddress ia = null;
String localname = null;
String localip = null;
String realcam = null;
try {
ia = ia.getLocalHost();
localname = ia.getHostName();
localip = ia.getHostAddress();
//System.out.println("本机名称是:" + localname);
//System.out.println("本机的ip是 :" + localip);
InetAddress ia1 = InetAddress.getLocalHost();// 获取本地IP对象,从该对象获取绑定的mac地址
// 获得网络接口对象(即网卡),并得到mac地址,mac地址存在于一个byte数组中。
byte[] mac = NetworkInterface.getByInetAddress(ia1).getHardwareAddress();
// 下面代码是把mac地址拼装成String
StringBuffer sb = new StringBuffer();
for (int i = 0; i < mac.length; i++) {
if (i != 0) {
sb.append("-");
}
// mac[i] & 0xFF 是为了把byte转化为正整数
String s = Integer.toHexString(mac[i] & 0xFF);
// System.out.println("--------------");
// System.err.println(s);
sb.append(s.length() == 1 ? 0 + s : s);
}
// 把字符串所有小写字母改为大写成为正规的mac地址并返回
realcam = sb.toString().toUpperCase();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
}
String sts = "本机名称是:"+localname+"\r|\n"+"本机的ip是 :"+localip+"\r\n"+"本机ip绑定的MAC是 :"+realcam+"\r\n";
return sts;
}
/***因为一台机器不一定只有一个网卡呀,所以返回的是数组是很合理的***/
public static 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 (network == null) {
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 String.join(",",tmpMacList);
}
/***去重,别忘了同一个网卡的ipv4,ipv6得到的mac都是一样的,肯定有重复,下面这段代码是。。流式处理***/
List<String> unique = tmpMacList.stream().distinct().collect(Collectors.toList());
String join = String.join(",", unique);
return join;
}
}