java怎样取得网卡物理地址
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java怎样取得网卡物理地址相关的知识,希望对你有一定的参考价值。
给你一个局域网的聊天程序或许对你有用!!!import java.net.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.GregorianCalendar;
import javax.swing.JDialog;
public class QQ extends Frame implements ActionListener
Label label1 = new Label("请输入您要发送的信息(限英文):");
Label label2 = new Label("以下是你收到的消息记录:");
Label label3 = new Label("把以上消息发给如下IP地址:");
TextArea input = new TextArea("", 7, 14, TextArea.SCROLLBARS_BOTH);
TextArea output = new TextArea("", 8, 14, TextArea.SCROLLBARS_BOTH);
TextField IPAdd = new TextField("192.168.1.88");
Button send = new Button("发送消息");
Button about = new Button("关于");
Button clear = new Button("清空消息纪录");
GregorianCalendar time = new GregorianCalendar();
QQ()
super("仿QQ聊天工具");
setLayout(null);
setLocation(250, 250);
this.setSize(518, 218);
this.setResizable(false); // 大小不可变
this.setBackground(new Color(220, 220, 220));
Toolkit kit = Toolkit.getDefaultToolkit();
Image myImage = kit.getImage("icons\\\\QQ.bmp");
this.setIconImage(myImage);
label1.setFont(new Font("宋体", Font.PLAIN, 12));
label1.setForeground(new Color(0, 0, 192));
label1.setBounds(8, 28, 216, 16);
input.setBackground(new Color(255, 255, 128));
input.setFont(new Font("Times New Roman", Font.BOLD, 15));
input.setForeground(Color.magenta);
input.setBounds(8, 44, 248, 120);
output.setBackground(new Color(128, 255, 255));
output.setFont(new Font("Times New Roman", Font.PLAIN, 12));
output.setForeground(Color.magenta);
output.setBounds(264, 44, 248, 136);
output.setEditable(false);
send.setFont(new Font("新宋体", Font.PLAIN, 12));
send.setLocation(136, 188);
send.setSize(120, 22);
clear.setFont(new Font("新宋体", Font.PLAIN, 12));
clear.setLocation(392, 188);
clear.setSize(120, 22);
label2.setFont(new Font("宋体", Font.PLAIN, 12));
label2.setForeground(new Color(0, 0, 192));
label2.setBounds(264, 28, 216, 16);
about.setFont(new Font("新宋体", Font.PLAIN, 12));
about.setLocation(264, 188);
about.setSize(120, 22);
label3.setFont(new Font("宋体", Font.PLAIN, 12));
label3.setForeground(new Color(0, 0, 192));
label3.setBounds(8, 172, 160, 16);
IPAdd.setFont(new Font("新宋体", Font.PLAIN, 12));
IPAdd.setLocation(8, 190);
IPAdd.setSize(120, 19);
add(label1);
add(input);
add(label3);
add(label2);
add(output);
add(IPAdd);
add(send);
add(about);
add(clear);
addWindowListener(new closeWin());
send.addActionListener(this);
about.addActionListener(this);
clear.addActionListener(this);
setVisible(true);
waitForData();
public void actionPerformed(ActionEvent e)
if (e.getSource() == send)
sendData();
else if (e.getSource() == clear)
output.setText("");
else if (e.getSource() == about)
AboutQQ test = new AboutQQ(this);
public static void main(String args[])
new QQ();
void sendData()
try
String msg = input.getText();
if (msg.equals(""))
return ;
input.setText("");
String ad = IPAdd.getText();
InetAddress tea = InetAddress.getLocalHost();
String asd = tea.getHostAddress();//发送方的IP地址
output.append("[" + asd + "]:(" + time.get(GregorianCalendar.YEAR)
+ "-" + time.get(GregorianCalendar.MONTH) + "-"
+ time.get(GregorianCalendar.DATE) + " "
+ time.get(GregorianCalendar.HOUR) + ":"
+ time.get(GregorianCalendar.MINUTE) + ":"
+ time.get(GregorianCalendar.SECOND) + ") " + "\\n" + msg
+ "\\n");
msg = "From [" + asd + "]:(" + time.get(GregorianCalendar.YEAR)
+ "-" + time.get(GregorianCalendar.MONTH) + "-"
+ time.get(GregorianCalendar.DATE) + " "
+ time.get(GregorianCalendar.HOUR) + ":"
+ time.get(GregorianCalendar.MINUTE) + ":"
+ time.get(GregorianCalendar.SECOND) + ") \\n" + msg;
InetAddress address = InetAddress.getByName(ad);
int len = msg.length();
byte[] message = new byte[len];
msg.getBytes(0, len, message, 0);
DatagramPacket packet = new DatagramPacket(message, len, address,
9999);
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
catch (Exception e)
void waitForData()
try
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
DatagramSocket socket = new DatagramSocket(9999);
while (true)
socket.receive(packet);
String s = new String(buffer, 0, 0, packet.getLength());
output.append(s + "\\n");
packet = new DatagramPacket(buffer, buffer.length);
catch (Exception e)
class closeWin extends WindowAdapter
public void windowClosing(WindowEvent e)
Frame fr = (Frame) (e.getSource());
fr.dispose();
System.exit(0);
class AboutQQ
private Label label;
private JDialog dialog;
public AboutQQ(Frame f)
label = new Label("Version 1.0");
dialog = new JDialog(f, "About", true);
dialog.setLocation(f.getLocation());
Container dialogPane = dialog.getContentPane();
dialogPane.setLayout(new BorderLayout());
dialogPane.add(label);
dialogPane.setBounds(50,50,50,50);
dialog.pack();
dialog.setVisible(true);
参考技术A InetAddress ip = InetAddress.getLocalHost();
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());
试试,应该是有效的
如何确定实际物理网卡的 MAC 地址——不是由 *** (.NET C#) 创建的虚拟网络接口
【中文标题】如何确定实际物理网卡的 MAC 地址——不是由 *** (.NET C#) 创建的虚拟网络接口【英文标题】:How to determine MAC Address of the actual physical network card -- not virtual network interfaces created by ***'s (.NET C#) 【发布时间】:2010-12-06 17:53:51 【问题描述】:背景
我正在尝试从计算机中获取唯一标识符,并希望每次都能可靠地返回相同的 MAC 地址。相信我,我有使用 MAC 地址的理由,并且阅读了许多关于替代唯一 ID 方法的帖子(是的,我考虑过他们是否没有任何网卡)。
问题
问题出在 .NET 中,我看不出特定的 NetworkInterface 是否是来自诸如“Nortel IPSECSHM Adapter - Packet Scheduler Miniport”之类的物理硬件网卡,当您连接到某些 *** 或WiFi 网络。
我知道如何使用类似下面的代码获取 Mac 地址:
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
log.Debug("NIC " + nic.OperationalStatus + " " + nic.NetworkInterfaceType + " " + nic.Speed + " " + nic.GetPhysicalAddress() + " " + nic.Description);
可以理解,没有 100% 的方法来确保我会获得内部网卡,但 我想选择 MAC 地址以返回给定机器最不可能更改的 MAC 地址强>。与诸如是否连接到 wifi...等因素无关...通过某种类型的系绳连接...或者他们安装了一些新的 *** 软件来添加新界面。
考虑的策略
1) 选择“Up”的第一个界面。这在我的笔记本电脑上失败了,因为“数据包微型端口”始终处于启动状态。此外,如果我将手机连接到笔记本电脑,这也会显示为第一张卡。
2) 选择最合适的类型...这失败了 b/c 基本上所有东西都显示为“以太网”,包括 WiFi 适配器和我的 iPHone 网络共享互联网连接。
3) 选择具有 IP 地址的 NIC。失败有几个原因:1)网卡可能没有连接到 LAN 2)有多个网卡可能有 IP 地址。
4) 只需发送所有 MAC 地址...问题是列表会根据安装的软件而变化,并且很难比较。
5) 选择速度最快的mac地址。我想这可能是我最好的选择。我认为可以肯定地说,最快的界面通常是最永久的。
或者,在 .NET 中可能有其他方法可以检测物理卡,或者如果您可以推荐一种可以提供不同信息的 API 调用,我会考虑调用其他 API。
还有其他想法吗?
在这里演示的是我的 iphone 系留时上面示例代码的输出:
DEBUG - NIC Down Ethernet 500000 0021E98BFBEF Apple Mobile Device Ethernet - Packet Scheduler Miniport
DEBUG - NIC Up Ethernet 10000000 444553544200 Nortel IPSECSHM Adapter - Packet Scheduler Miniport
DEBUG - NIC Down Ethernet 54000000 00166FAC94C7 Intel(R) PRO/Wireless 2200BG Network Connection - Packet Scheduler Miniport
DEBUG - NIC Down Ethernet 1000000000 0016D326E957 Broadcom NetXtreme Gigabit Ethernet - Packet Scheduler Miniport
DEBUG - NIC Up Loopback 10000000 MS TCP Loopback interface
没有连接 Iphone:
DEBUG - NIC Up Ethernet 10000000 444553544200 Nortel IPSECSHM Adapter - Packet Scheduler Miniport
DEBUG - NIC Down Ethernet 54000000 00166FAC94C7 Intel(R) PRO/Wireless 2200BG Network Connection - Packet Scheduler Miniport
DEBUG - NIC Down Ethernet 1000000000 0016D326E957 Broadcom NetXtreme Gigabit Ethernet - Packet Scheduler Miniport
DEBUG - NIC Up Loopback 10000000 MS TCP Loopback interface
【问题讨论】:
您还应该考虑具有多个相同类型 NIC 的计算机。 您不能依赖 MAC 地址作为唯一标识符。如果您想要一个唯一标识符,请生成一个 GUID,对其进行加密并将其存储在计算机上。 @John Saunders,我确实使用 GUID。 MAC 地址是一个备份,以防 GUID 的存储位置被删除。 查看我的回答***.com/a/40088578/1498252 以检查物理设备。 【参考方案1】:这是我的方法: 它利用物理卡连接到PCI接口的事实
ManagementObjectSearcher searcher = new ManagementObjectSearcher
("Select MACAddress,PNPDeviceID FROM Win32_NetworkAdapter WHERE MACAddress IS NOT NULL AND PNPDeviceID IS NOT NULL");
ManagementObjectCollection mObject = searcher.Get();
foreach (ManagementObject obj in mObject)
string pnp = obj["PNPDeviceID"].ToString();
if (pnp.Contains("PCI\\"))
string mac = obj["MACAddress"].ToString();
mac = mac.Replace(":", string.Empty);
return mac;
【讨论】:
我不认为这会满足这样的需求:amazon.co.uk/Belkin-Ethernet-Adapter-Patch-Cable/dp/B0002AFKN0 - 但是它们并不是那么普遍。 是的,这是个问题。我没有这样的设备,有趣的是,在这种情况下,“PNPDeviceID”中写的是什么。第二个问题是当有不止一张卡时。因为我总是取“第一张”牌,所以在“选择”运算符中的牌顺序不确定的情况下可能会导致错误。我没有在这个“SQL for WMI”方言中找到“order by”结构:) 我有一个适配器,其标题为“Broadcom BCM5709C NetXtreme II GigE(NDIS VBD 客户端)”和没有“PCI\”的 PNPDeviceID。它是物理的。 如何获取物理适配器的 IPv4 地址? (远程计算机)PhysicalAdapter
?网络适配器属性名称:NetEnabled - 值:True 网络适配器属性名称:PhysicalAdapter - 值:True 网络适配器属性名称:PNPDeviceID -值:PCI\VEN_15AD&DE【参考方案2】:
MAC 地址的前三个字节是制造商 ID。您可以将某些已知不适合您的制造商 ID 列入黑名单,并忽略这些接口。
依赖速度可能不是一个好主意,因为 *** 接口没有理由不能报告自己具有千兆速度。
【讨论】:
我考虑过列入黑名单...我认为根据描述中出现的字符串(例如:“***”、“IPSECSHM”...但是认为这很难想出。或者,我想我可以创建一个最流行的网络接口的白名单......“Realtek”,“Gigabit” - 我真的想避免创建和维护一个白名单。【参考方案3】:MAC 地址是物理硬件地址。我无法在这台电脑上进行测试,但我认为如果添加虚拟连接,您将不会获得新的 MAC 地址,因为它不是实际的硬件。这将是另一个连接,但不是另一个 MAC 地址。
因此,确保您每次都获得相同的 MAC 地址取决于连接到机器的相同硬件,并且您使用相同的算法从该硬件中进行选择。
【讨论】:
@Brian - MAC 地址也用于虚拟接口......在我的例子中是 Nortel Packet 接口。【参考方案4】:我也一直在研究这个问题,并且相信如果没有持久状态,就很难维持稳定的 MAC。
我正在玩弄的解决方案是获取在适配器顺序中找到的第一个 NIC,然后使用它并保存它。然后在后续的 UUID 生成中,如果在堆栈中的任何位置找到保存的 MAC,即使不是第一个,也要使用它。这样适配器订单可以移动,我们不用担心会炸毁任何依赖于稳定 MAC(例如许可模块)的东西。
如果在堆栈中找不到保存的 MAC,则将其丢弃,我们只需使用绑定顺序中的第一个 MAC 并重新开始。
【讨论】:
【参考方案5】: public static string GetMacAddressPhysicalNetworkInterface()
ManagementObjectSearcher searcher = new ManagementObjectSearcher
("Select MACAddress,PNPDeviceID FROM Win32_NetworkAdapter WHERE MACAddress IS NOT NULL AND" +
" PNPDeviceID IS NOT NULL AND" +
" PhysicalAdapter = true");
ManagementObjectCollection mObject = searcher.Get();
string macs = (from ManagementObject obj in mObject
let pnp = obj["PNPDeviceID"].ToString()
where !(pnp.Contains("ROOT\\"))
//where pnp.Contains("PCI\\") || pnp.Contains("USB\\")
select obj).Select(obj => obj["MACAddress"].ToString())
.Aggregate<string, string>(null, (mac, currentMac) => mac + currentMac.Replace(":", string.Empty) + ",");
return !string.IsNullOrEmpty(macs) ? macs.Substring(0, macs.Length - 1) : macs;
public static NetworkInterface GetPhysicalNetworkInterface(string macAddressPhysicalNetworkInterface)
return NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(currentNetworkInterface => string.Equals(currentNetworkInterface.GetPhysicalAddress().ToString(), macAddressPhysicalNetworkInterface, StringComparison.CurrentCultureIgnoreCase));
【讨论】:
一些解释/文档链接解释了为什么这个答案比其他答案更好会有所帮助。我确实喜欢“physicaladapter = true”检查,但可以依赖它吗? 勾选这个属性也够了 如何使用scope = "\\\\" + ip + "\\root\\cimv2";
获取GetPhysicalNetworkInterface
?以上是关于java怎样取得网卡物理地址的主要内容,如果未能解决你的问题,请参考以下文章
怎样改变eth0,eth1,eth2,eth3所对应的物理网卡