Qt网络编程-使用QNetworkInterface获取网卡信息和IP地址Demo(7) 原创
Qt网络编程-使用QNetworkInterface获取网卡信息和IP地址Demo(7)🎧
更多精彩内容 |
---|
👉个人内容分类汇总 👈 |
1、概述📻
Qt使用QNetworkInterface获取当前系统的网卡信息和IP地址信息,注意:Qt版本5.12.12,程序中有些功能比较新,在版本比较低在Qt中可能没有,比如:QNetworkInterface::type()在5.11以后才有 |
第一,绝对不意气用事;
第二,绝对不放过任何一个注释;
第三,绝对保证代码的简洁明了。🤘
在Qt实现网络通信时,常常需要获取本地IP地址或者网卡信息,例如两个TCP通信,需要知道对方IP地址,又不想每次都ipcofnig查询,想在程序中自动获取IP地址,那就需要看看本文了;
而当系统有多个网卡或者多个IP地址时,单独的知道一个IP地址是不够的,就需要获取所有的网卡信息和所有的IP地址信息。
实现功能:
- 获取所有网络接口;
- 获取网络接口索引;
- 获取网络接口最大传输数据单元;
- 获取网络接口名称;
- 获取网络接口关联标志;
- 获取网络接口类型说明;
- 获取网络接口物理地址;
- 获取IPv6地址、子网掩码
- 获取IPv4地址、子网掩码、广播地址。
2、使用的类🎷
类名 | 作用 |
---|---|
QNetworkInterface | 用于获取网卡详细信息和IP、子网掩码、广播地址等信息 |
QNetworkAddressEntry | 包含IP、子网掩码、广播地址等信息 |
3、关键函数 🎸
函数名 | 说明 |
---|---|
allInterfaces | 返回主机上找到的所有网络接口(网卡)的列表 |
humanReadableName | 返回可以读懂的接口名称,如果名称不确定,得到的就是name函数的返回值 |
interfaceFromName | 根据输入网络接口名称参数,返回名为 name 的接口的 QNetworkInterface 对象 |
index | 返回网络接口的索引 |
maximumTransmissionUnit | 返回网络接口的最大传输数据单元。 |
name | 返回网络接口名称 |
flags | 返回网络接口关联标志枚举 |
type | 返回网络接口类型(如以太网、wifi、虚拟网卡) |
hardwareAddress | 返回网络接口的物理地址(MAC地址) |
addressEntries | 返回网络接口中所有QNetworkAddressEntry对象 |
4、主要代码🎹
- 注意:在
.pro
文件里添加QT += network
,否则编译失败。 - .h文件
/******************************************************************************
* @文件名 netproperty.h
* @功能 使用QNetworkInterface类获取当前系统所有的网卡信息,如IP地址,物理地址,网卡类型等
*
* @开发者 mhf
* @邮箱 1603291350@qq.com
* @时间 2022/04/22
* @备注
*****************************************************************************/
#ifndef NETPROPERTY_H
#define NETPROPERTY_H
#include <QWidget>
namespace Ui {
class NetProperty;
}
class NetProperty : public QWidget
{
Q_OBJECT
public:
explicit NetProperty(QWidget *parent = nullptr);
~NetProperty();
private slots:
void on_com_Interface_activated(int index);
private:
void init();
QString TypeToQString(int type);
private:
Ui::NetProperty *ui;
};
#endif // NETPROPERTY_H
- .cpp文件
#include "netproperty.h"
#include "ui_netproperty.h"
#include <QMetaEnum>
#include <qnetworkinterface.h>
#include <QDeadlineTimer>
NetProperty::NetProperty(QWidget *parent) :
QWidget(parent),
ui(new Ui::NetProperty)
{
ui->setupUi(this);
this->setWindowTitle("Qt使用QNetworkInterface获取网卡信息、IP地址Demo");
// 表格自适应
ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); // 设置如何将标题大小调整为给定模式所述大小的约束。
ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents); // 然后设置要根据内容使用宽度的列
init();
}
NetProperty::~NetProperty()
{
delete ui;
}
/**
* @brief 获取所有的网卡可读名称
*/
void NetProperty::init()
{
// 获取所有网络接口
const QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
ui->com_Interface->clear();
for(const QNetworkInterface& interface : interfaces)
{
ui->com_Interface->addItem(interface.humanReadableName(), interface.name()); // 显示所有网络接口名称
}
}
/**
* @brief 通过下列框选择网卡名,显示选择网卡的所有信息
* @param index
*/
void NetProperty::on_com_Interface_activated(int index)
{
Q_UNUSED(index)
QString strName = ui->com_Interface->currentData().toString();
QNetworkInterface interface = QNetworkInterface::interfaceFromName(strName); // 根据选择名称获取网卡
if(!interface.isValid()) // 判断接口有效
{
return;
}
ui->tableWidget->item(0, 1)->setText(QString::number(interface.index())); // 获取网卡索引
ui->tableWidget->item(1, 1)->setText(QString::number(interface.maximumTransmissionUnit())); // 获取网卡最大传输数据单元
ui->tableWidget->item(2, 1)->setText(interface.name()); // 获取网卡名称
#if 0 // 直接显示标志枚举
QNetworkInterface::InterfaceFlags flags = interface.flags();
QMetaEnum metaEnum = QMetaEnum::fromType<QNetworkInterface::InterfaceFlags>();
ui->tableWidget->item(3, 1)->setText(metaEnum.valueToKeys(flags)); // 返回与此网络接口关联的标志
#else
ui->tableWidget->item(3, 1)->setText(FlagsToQString(interface.flags()));
#endif
ui->tableWidget->item(4, 1)->setText(TypeToQString(interface.type())); // 获取网络类型说明
ui->tableWidget->item(5, 1)->setText(interface.hardwareAddress()); // // 获取MAC地址
ui->textEdit_ip->clear();
// 如果只是获取所有的IP地址可以使用allAddresses()函数
const QList<QNetworkAddressEntry> entrys = interface.addressEntries(); // 返回此接口拥有的 IP 地址列表及其关联的网络掩码和广播地址。
for(auto entery : entrys)
{
QString strType;
switch (entery.ip().protocol()) // 判断IP地址类型
{
case QAbstractSocket::IPv4Protocol:
strType = "--------IPv4地址--------";
break;
case QAbstractSocket::IPv6Protocol:
strType = "--------IPv6地址--------";
break;
case QAbstractSocket::AnyIPProtocol:
strType = "--------IPv4或IPv6地址--------";
break;
case QAbstractSocket::UnknownNetworkLayerProtocol:
strType = "--------未知地址--------";
break;
}
ui->textEdit_ip->append(strType); // 显示IP地址类型
QString ipInfo = QString("IP地址:%1,子网掩码:%2,广播地址:%3").arg(entery.ip().toString())
.arg(entery.netmask().toString())
.arg(entery.broadcast().toString());
ui->textEdit_ip->append(ipInfo); // 显示IP地址信息
}
}
/**
* @brief 将网卡关联标志转换为可读的说明信息
* @param flags
* @return
*/
QString NetProperty::FlagsToQString(int flags)
{
QString strFlags;
if(flags & QNetworkInterface::IsUp)
{
strFlags += "网络接口处于活动状态";
}
if(flags & QNetworkInterface::IsRunning)
{
strFlags.append(strFlags.isEmpty() ? "" : " | ");
strFlags += "网络接口已分配资源";
}
if(flags & QNetworkInterface::CanBroadcast)
{
strFlags.append(strFlags.isEmpty() ? "" : " | ");
strFlags += "网络接口工作在广播模式";
}
if(flags & QNetworkInterface::IsLoopBack)
{
strFlags.append(strFlags.isEmpty() ? "" : " | ");
strFlags += "网络接口是一个环回接口";
}
if(flags & QNetworkInterface::IsPointToPoint)
{
strFlags.append(strFlags.isEmpty() ? "" : " | ");
strFlags += "网络接口是一个点对点接口";
}
if(flags & QNetworkInterface::CanMulticast)
{
strFlags.append(strFlags.isEmpty() ? "" : " | ");
strFlags += "网络接口支持组播";
}
return strFlags;
}
/**
* @brief 返回网卡类型说明
* @param type 网卡类型枚举
* @return 网卡类型说明
*/
QString NetProperty::TypeToQString(int type)
{
switch (type)
{
case QNetworkInterface::Loopback: return "虚拟环回接口,分配了环回 IP 地址 (127.0.0.1, ::1)";
case QNetworkInterface::Virtual: return "一种确定为虚拟的接口类型,但不是任何其他可能的类型";
case QNetworkInterface::Ethernet: return "IEEE 802.3 以太网接口";
case QNetworkInterface::Slip: return "串行线路互联网协议接口";
case QNetworkInterface::CanBus: return "ISO 11898 控制器局域网总线接口";
case QNetworkInterface::Ppp: return "点对点协议接口,通过较低的传输层(通常通过无线电或物理线路串行)在两个节点之间建立直接连接";
case QNetworkInterface::Fddi: return "ANSI X3T12 光纤分布式数据接口,一种光纤局域网";
case QNetworkInterface::Wifi: return "IEEE 802.11 Wi-Fi 接口"; // 别名 Ieee80211
case QNetworkInterface::Phonet: return "使用 Linux Phonet socket系列的接口,用于与蜂窝调制解调器通信";
case QNetworkInterface::Ieee802154: return "IEEE 802.15.4 个人区域网络接口,6LoWPAN 除外";
case QNetworkInterface::SixLoWPAN: return "6LoWPAN(低功耗无线个人区域网络上的 IPv6)接口,通常用于网状网络";
case QNetworkInterface::Ieee80216: return "IEEE 802.16 无线城域网";
case QNetworkInterface::Ieee1394: return "IEEE 1394 接口(又名“FireWire”)";
case QNetworkInterface::Unknown: return "接口类型无法确定或不是其他列出的类型之一";
default:return "未知";
}
}
5、实现效果🎺
6、源代码🥁
📞📞📞📞📞📞📞📞📞📞📞📞