Qt网络编程-主机信息查询
前言:
查询一个主机的MAC地址或IP地址是网络应用程序中经常用到的功能,Qt提供了QHostInfo类和QNetworkInterface类
可以用于此类信息的查询,完整代码见QT主机信息查询程序
运行效果图:
QHostInfo类
主要功能函数介绍(红色字体为本程序使用到)
类别 | 函数原型 | 作用 |
---|---|---|
公共函数 | QList<QHostAddress> addresses() | 返回与主机hostName()关联的IP地址列表 |
公共函数 | HostInfoError error() | 如果主机查找失败,返回失败类型 |
公共函数 | QString errorString() | 如果主机查找失败,返回错误描述字符串 |
公共函数 | QString hostName() | 通过IP查找的主机的名称 |
公共函数 | int lookupId() | 返回本次查找的ID |
静态函数 | void abortHostLookup(int id) | 根据id中断主机查找 |
静态函数 | QHostInfo fromName(QString &name) | 返回指定的主机名的IP地址 |
静态函数 | QString localDomainName() | 返回本机DNS域名 |
静态函数 | QString localHostName() | 返回本机主机名字 |
静态函数 | int lookupHost(QString& name,QObject* receiver,char* member) | 以异步的方式根据主机名查找主机的IP地址,并返回一个表示本次查找的额ID,可用于abortHostLookup() |
QHostInfo的使用
1)显示本机地址信息
- 通过协议类型返回协议名称
QString myWidget::protocolNmae(QAbstractSocket::NetworkLayerProtocol protocol)
{
switch (protocol)
{
case QAbstractSocket::IPv4Protocol:
return "IPV4 Protocol";
case QAbstractSocket::IPv6Protocol:
return "IPV6 Protocol";
case QAbstractSocket::AnyIPProtocol:
return "Any IP Protocol";
default:
return "Unkown Network Layer Protocol";
}
}
- 获取信息按钮槽函数
void myWidget::on_btnGetHostInfo_clicked()
{
//返回主机名
QString hostname = QHostInfo::localHostName();
ui->plainTextEdit->appendPlainText("本机名称:"+hostname);
//返回主机信息
QHostInfo hostInfo = QHostInfo::fromName(hostname);
//返回IP地址列表
QList<QHostAddress> addList = hostInfo.addresses();
//判断IP地址列表是否为空
if(!addList.isEmpty())
//遍历IP地址列表,输出主机信息
for(int i=0;i<addList.count();i++)
{
QHostAddress aHost = addList.at(i);
//输出IPV4信息
if(ui->chkIPV4->isChecked()&&(QAbstractSocket::IPv4Protocol==aHost.protocol()))
{
ui->plainTextEdit->appendPlainText("协议: "+protocolNmae(aHost.protocol()));
ui->plainTextEdit->appendPlainText("本机IPV4地址: "+aHost.toString());
ui->plainTextEdit->appendPlainText("");
}
//输出IPV6信息
if(ui->chkIPV6->isChecked()&&(QAbstractSocket::IPv6Protocol==aHost.protocol()))
{
ui->plainTextEdit->appendPlainText("协议: "+protocolNmae(aHost.protocol()));
ui->plainTextEdit->appendPlainText("本机IPV6地址: "+aHost.toString());
ui->plainTextEdit->appendPlainText("");
}
}
}
2)查找主机地址信息
- 在行编辑框输入要查找的主机名,域名,或IP地址,通过槽函数得到主机信息
void myWidget::on_btnLookUp_clicked()
{
QString hostname = ui->lineEdit->text();
ui->plainTextEdit->appendPlainText("正在查找主机信息:"+hostname);
QHostInfo::lookupHost(hostname,this,SLOT(OnLookuphostinfo(QHostInfo)));
}
- 查找的槽函数
void myWidget::OnLookuphostinfo(const QHostInfo &host)
{
//返回QHostInfo::NoError为查找成功
if (host.error() != QHostInfo::NoError)
{
ui->plainTextEdit->appendPlainText("Lookup Failed:"+host.errorString());
return;
}
//和上面遍历一样,用foreach()完成
foreach(const QHostAddress &aHost,host.addresses())
{
if(ui->chkIPV4->isChecked()&&(QAbstractSocket::IPv4Protocol==aHost.protocol()))
{
ui->plainTextEdit->appendPlainText("协议: "+protocolNmae(aHost.protocol()));
ui->plainTextEdit->appendPlainText("本机IPV4地址: "+aHost.toString());
ui->plainTextEdit->appendPlainText("");
}
if(ui->chkIPV6->isChecked()&&(QAbstractSocket::IPv6Protocol==aHost.protocol()))
{
ui->plainTextEdit->appendPlainText("协议: "+protocolNmae(aHost.protocol()));
ui->plainTextEdit->appendPlainText("本机IPV6地址: "+aHost.toString());
ui->plainTextEdit->appendPlainText("");
}
}
}
QNetworkInterface类
QNetWorkInterface可以获得应用程序所在主机的所有网络接口,包括其子网掩码和广播地址等
主要功能函数介绍(本程序用到的)
类别 | 函数原型 | 作用 |
---|---|---|
公共函数 | QList<QNetworkAddressEntry> addressEntries() | 返回该网口(包括子网掩码和广播地址)的IP地址 |
公共函数 | QString hardwareAddress() | 返回该接口的低级硬件地址,以太网就是MAC地址 |
公共函数 | QString humanReadableName() | 返回可以读懂的接口名称,如果名称不确定,得到的就是name()函数的返回值 |
公共函数 | bool isValid() | 如果接口信息有效就返回true |
公共函数 | QString name()) | 返回网络接口名称 |
静态函数 | QList<QHostAddress> allAddresses() | 返回主机上所有IP地址的列表 |
静态函数 | QList<QNetworkInterface> allInterfaces() | 返回主机上所有接口的网络列表 |
QNetworkInterface的使用
- 只获取主机上所有IP地址的列表
//用QNetworkInterface::allAddresses()获取IP地址列表
void myWidget::on_btnAllAddress_clicked()
{
foreach(const QHostAddress &aHost,QNetworkInterface::allAddresses())
{
if(ui->chkIPV4->isChecked()&&(QAbstractSocket::IPv4Protocol==aHost.protocol()))
{
ui->plainTextEdit->appendPlainText("协议: "+protocolNmae(aHost.protocol()));
ui->plainTextEdit->appendPlainText("IPV4地址: "+aHost.toString());
ui->plainTextEdit->appendPlainText("");
}
if(ui->chkIPV6->isChecked()&&(QAbstractSocket::IPv6Protocol==aHost.protocol()))
{
ui->plainTextEdit->appendPlainText("协议: "+protocolNmae(aHost.protocol()));
ui->plainTextEdit->appendPlainText("IPV6地址: "+aHost.toString());
ui->plainTextEdit->appendPlainText("");
}
}
}
- 获取所在主机所有的网络接口
//用QNetworkInterface::allInterfaces()获取所有网络接口的列表
//每个网络接口又有一个QNetworkAddressEntry类型的地址列表,通过addressEntries()获取
void myWidget::on_btnAllInterfaces_clicked()
{
QList<QNetworkInterface> list =QNetworkInterface::allInterfaces();
for(int i=0;i<list.count();i++)
{
QNetworkInterface aInterface = list.at(i);
//判断接口信息是否有效
if(!aInterface.isValid())
continue;
ui->plainTextEdit->appendPlainText("设备地址: "+aInterface.humanReadableName());
ui->plainTextEdit->appendPlainText("硬件地址: "+aInterface.hardwareAddress());
QList<QNetworkAddressEntry> entryList = aInterface.addressEntries();
foreach(const QNetworkAddressEntry& aEntry,entryList)
{
ui->plainTextEdit->appendPlainText("IP地址: "+aEntry.ip().toString());
ui->plainTextEdit->appendPlainText("子网掩码: "+aEntry.netmask().toString());
ui->plainTextEdit->appendPlainText("广播地址: "+aEntry.broadcast().toString()+"\n");
}
ui->plainTextEdit->appendPlainText("\n");
}
}