Qt/C++ : 如何获取远程PC(通讯端)MAC地址?
Qt/C++ : How to get remote PC (communication peer) MAC address?
我在 Windows 7.
上使用 Qt5
在我的应用程序(TCP 服务器)中,我目前正在使用 QTcpSocket class:
中的一些方法
- QAbstractSocket::peerAddress()
为了获得 对等地址 ;
- QAbstractSocket::peerPort()
以获得 对等端口 。
我也想得到通信对端的MAC地址
这是否可能,而不使用自定义协议(即无需在我的应用程序和对等方之间交换一些自定义消息)?如果是,如何?
后期编辑:现在有 - 我几个月前实施的。我同时测试了它,它 100% 完美地工作。享受:)
一般来说,不,这是不可能的,因为通信对等方甚至可能没有 MAC 地址(例如,如果它使用的是不基于以太网的网络硬件)。特别是,有关 MAC 地址的信息不会通过 IP、TCP 或 UDP 层进行通信——这些层使用 IP 地址代替。因此,如果您想找出对等方的 MAC 地址,您需要在应用程序级别执行此操作,方法是让对等方的程序将其发送给您。
(上述的一个小例外:如果您通过 IPv6 通信并使用自分配的 link-本地 IPv6 地址(例如 fe80::blah),则可以 derive 计算机的 MAC 地址来自其自分配的 IPv6 地址,因为自分配的 IPv6 地址通常派生自 MAC 地址并包含 MAC 地址作为其 IPv6 的子集地址。[请注意,这在 Internet 上不起作用,因为 link- 本地地址仅在两台机器位于同一 LAN 上时才有用])
如果远程对等点与程序的主机在同一个 LAN 上(并且 LAN 是以太网 LAN),则该程序可能正在使用一些 Windows-特定的 API 来查找IPAddress<->MAC机器ARP中的地址映射table。如果远程点在 Internet 的其他地方,那么我不知道它是怎么做到的。
这里是获取通信对端MAC地址的代码。
在幕后,它使用 Windows 命令 arp.
使用 Qt5.8,在 Windows 7 上测试:
QString getMacForIP(QString ipAddress)
{
QString MAC;
QProcess process;
//
process.start(QString("arp -a %1").arg(ipAddress));
if(process.waitForFinished())
{
QString result = process.readAll();
QStringList list = result.split(QRegularExpression("\s+"));
if(list.contains(ipAddress))
MAC = list.at(list.indexOf(ipAddress) + 1);
}
//
return MAC;
}
备注:远程端必须在同一局域网内。
另一条评论:如果 IP 地址不存在,您将得到一个空字符串 MAC。
如果您可以运行远程对等端的代码,MAC地址可以通过hardwareAddress()接口调用报告。
例如,要报告 WiFi 接口的 MAC 地址,以及该接口上的所有 IPv4 地址:
for(const QNetworkInterface& iface: QNetworkInterface::allInterfaces()){
if (iface.type() == QNetworkInterface::Wifi){
qDebug() << "MAC:" << iface.hardwareAddress();
for (const QHostAddress& addr : iface.allAddresses()){
if (addr.protocol() == QAbstractSocket::IPv4Protocol)
qDebug() << "IPv4 Addr: " << addr;
}
}
}
我在 Windows 7.
上使用 Qt5
在我的应用程序(TCP 服务器)中,我目前正在使用 QTcpSocket class:
中的一些方法
- QAbstractSocket::peerAddress()
为了获得 对等地址 ;
- QAbstractSocket::peerPort()
以获得 对等端口 。
我也想得到通信对端的MAC地址
这是否可能,而不使用自定义协议(即无需在我的应用程序和对等方之间交换一些自定义消息)?如果是,如何?
后期编辑:现在有
一般来说,不,这是不可能的,因为通信对等方甚至可能没有 MAC 地址(例如,如果它使用的是不基于以太网的网络硬件)。特别是,有关 MAC 地址的信息不会通过 IP、TCP 或 UDP 层进行通信——这些层使用 IP 地址代替。因此,如果您想找出对等方的 MAC 地址,您需要在应用程序级别执行此操作,方法是让对等方的程序将其发送给您。
(上述的一个小例外:如果您通过 IPv6 通信并使用自分配的 link-本地 IPv6 地址(例如 fe80::blah),则可以 derive 计算机的 MAC 地址来自其自分配的 IPv6 地址,因为自分配的 IPv6 地址通常派生自 MAC 地址并包含 MAC 地址作为其 IPv6 的子集地址。[请注意,这在 Internet 上不起作用,因为 link- 本地地址仅在两台机器位于同一 LAN 上时才有用])
如果远程对等点与程序的主机在同一个 LAN 上(并且 LAN 是以太网 LAN),则该程序可能正在使用一些 Windows-特定的 API 来查找IPAddress<->MAC机器ARP中的地址映射table。如果远程点在 Internet 的其他地方,那么我不知道它是怎么做到的。
这里是获取通信对端MAC地址的代码。
在幕后,它使用 Windows 命令 arp.
使用 Qt5.8,在 Windows 7 上测试:
QString getMacForIP(QString ipAddress)
{
QString MAC;
QProcess process;
//
process.start(QString("arp -a %1").arg(ipAddress));
if(process.waitForFinished())
{
QString result = process.readAll();
QStringList list = result.split(QRegularExpression("\s+"));
if(list.contains(ipAddress))
MAC = list.at(list.indexOf(ipAddress) + 1);
}
//
return MAC;
}
备注:远程端必须在同一局域网内。
另一条评论:如果 IP 地址不存在,您将得到一个空字符串 MAC。
如果您可以运行远程对等端的代码,MAC地址可以通过hardwareAddress()接口调用报告。
例如,要报告 WiFi 接口的 MAC 地址,以及该接口上的所有 IPv4 地址:
for(const QNetworkInterface& iface: QNetworkInterface::allInterfaces()){
if (iface.type() == QNetworkInterface::Wifi){
qDebug() << "MAC:" << iface.hardwareAddress();
for (const QHostAddress& addr : iface.allAddresses()){
if (addr.protocol() == QAbstractSocket::IPv4Protocol)
qDebug() << "IPv4 Addr: " << addr;
}
}
}