Qt: Как получить MAC-адрес удаленного ПК (узла связи)?
Я использую Qt5 на Windows 7.
В моем приложении (сервер TCP) в настоящее время я использую некоторые методы из класса QTcpSocket:
- QAbstractSocket::peerAddress()
для того, чтобы получить адрес партнера;
- QAbstractSocket::peerPort()
для того, чтобы получить одноранговый порт.
Я также хотел бы получить MAC-адрес узла связи.
Возможно ли это без использования специального протокола (т.е. без необходимости обмена некоторыми пользовательскими сообщениями между моим приложением и партнером)? Если да, то как?
2 ответа
Я также хотел бы получить MAC-адрес узла связи. Возможно ли это без использования специального протокола (т.е. без необходимости обмена некоторыми пользовательскими сообщениями между моим приложением и партнером)? Если да, то как?
В общем, нет, это невозможно, так как узел связи может даже не иметь MAC-адреса (например, если он использует сетевое оборудование, не основанное на Ethernet). В частности, информация о MAC-адресах не передается уровнями IP, TCP или UDP - эти уровни вместо этого используют IP-адреса. Поэтому, если вы хотите узнать MAC-адрес однорангового узла, вам нужно будет сделать это на уровне приложения, если программа на одноранговом узле отправит его вам.
(Одно незначительное исключение из вышеперечисленного: если вы общаетесь через IPv6 и используете самоназначенные локальные IPv6-адреса каналов (например, fe80::blah), можно получить MAC-адрес компьютера из его самоназначенного IPv6-адреса, потому что самоназначенный IPv6-адрес обычно получается из MAC-адреса и содержит MAC-адрес в качестве подмножества своего IPv6-адреса. [Обратите внимание, что это не будет работать через Интернет, так как локальные адреса канала полезны только тогда, когда обе машины расположены на та же ЛВС])
Вот код для получения 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;
}
Примечание: удаленный узел должен быть в той же локальной сети.
Еще одно замечание: вы получите пустую строку для MAC, если IP-адрес отсутствует.
Если вы можете запустить код на удаленном узле, MAC-адрес можно сообщить с помощью вызова hardwareAddress() интерфейса.
Например, чтобы сообщить MAC-адрес интерфейса WiFi и все адреса 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;
}
}
}