一、演示demo
1.1代码示例
1.1.1 h头文件
#ifndef FORM_H
#define FORM_H
#include <QWidget>
#include "TitleBar/basewidget.h"
#include "TitleBar/commonhelp.h"
#include<QAbstractSocket>
#include<QHostInfo>
namespace Ui {
class Form;
}
class Form : public BaseWidget
{
Q_OBJECT
public:
/**
* @brief 构造函数
* @param parent [in] parent指针
*/
explicit Form(QWidget *parent = nullptr);
~Form();
/**
* @brief 获取协议类型
* @param protocal [in] 协议类型
*/
QString protocalName(QAbstractSocket::NetworkLayerProtocol protocal);
private slots:
/**
* @brief 主机信息主机名和IP
* @param host [in] 主机信息
*/
void lookedUpHostInfo(const QHostInfo &host);
private slots:
/**
* @brief 获取主机信息槽函数
* @param
*/
void on_btnGetHostInfo_clicked();
/**
* @brief 清空槽函数
* @param
*/
void on_btnClear_clicked();
/**
* @brief 获取所有网络信息槽函数
* @param
*/
void on_btnAllInterfaces_clicked();
/**
* @brief 主机信息IP槽函数
* @param
*/
void on_btnAllAdderse_clicked();
/**
* @brief 查找域名和IP地址槽函数
* @param
*/
void on_btnLookUp_clicked();
private:
Ui::Form *ui;
};
#endif // FORM_H
1.1.2 cpp文件
#include "form.h"
#include "ui_form.h"
#include<QHostInfo>
#include<QNetworkInterface>
Form::Form(QWidget *parent) :
BaseWidget(parent),
ui(new Ui::Form)
{
ui->setupUi(this);
setWindowTitle(QStringLiteral("qt网络编程"));
setTitleBarIcon("E:/F盘/user_operator.png");
QGridLayout* lay = new QGridLayout;
lay->addWidget(ui->widget);
lay->setContentsMargins(0,0,0,0);
contentWidget()->setLayout(lay);
setWindowTitleHeight(60);
CommonHelper::setStyleSheet(":/user3.qss");
setBackgroundColor(56,61,70,false);
}
Form::~Form()
{
delete ui;
}
QString Form::protocalName(QAbstractSocket::NetworkLayerProtocol protocal)
{
switch (protocal) {
case QAbstractSocket::IPv4Protocol:
return "IPV4 protocal";
case QAbstractSocket::IPv6Protocol:
return "IPV6 protocal";
case QAbstractSocket::AnyIPProtocol:
return "Any IP protocal";
default:
return "Unknown NetWork protocal";
}
}
void Form::lookedUpHostInfo(const QHostInfo &host)
{
QList<QHostAddress> addList=host.addresses();
if(!addList.isEmpty())
{
for(int i=0;i<addList.count();i++)
{
QHostAddress aHost=addList.at(i);
bool show=ui->cheOnlyIPV4->isChecked();
if(show)
show=(QAbstractSocket::IPv4Protocol==aHost.protocol());
else {
show=true;
}
if(show)
{
ui->plainTextEdit->appendPlainText("协议:"+protocalName(aHost.protocol()));
ui->plainTextEdit->appendPlainText(aHost.toString());
}
}
}
}
void Form::on_btnGetHostInfo_clicked()
{
QString hostName=QHostInfo::localHostName();
ui->plainTextEdit->appendPlainText("本机主机名:"+hostName+"\n");
QHostInfo hostInfo=QHostInfo::fromName(hostName);
QList<QHostAddress> addList=hostInfo.addresses();
if(!addList.isEmpty())
{
for(int i=0;i<addList.count();i++)
{
QHostAddress aHost=addList.at(i);
bool show=ui->cheOnlyIPV4->isChecked();
if(show)
{
show=(QAbstractSocket::IPv4Protocol==aHost.protocol());
}
else {
show=true;
}
if(show)
{
ui->plainTextEdit->appendPlainText("协议:"+protocalName(aHost.protocol()));
ui->plainTextEdit->appendPlainText("本机IP地址:"+aHost.toString());
ui->plainTextEdit->appendPlainText(" ");
}
}
}
}
void Form::on_btnClear_clicked()
{
ui->plainTextEdit->clear();
}
void Form::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();
for(int j=0;j<entryList.count();j++)
{
QNetworkAddressEntry aEntry=entryList.at(j);
ui->plainTextEdit->appendPlainText("IP地址:"+aEntry.ip().toString());
ui->plainTextEdit->appendPlainText("子网掩码:"+aEntry.netmask().toString());
ui->plainTextEdit->appendPlainText("广播地址:"+aEntry.broadcast().toString()+"\n");
}
ui->plainTextEdit->appendPlainText("\n");
}
}
void Form::on_btnAllAdderse_clicked()
{
//获取所有网络接口的列表
QList<QNetworkInterface> list=QNetworkInterface::allInterfaces();
//显示每个接口的humanReadable Name()和hardwareAddress()。每个接口又有一个QNetworkAddressEntry类型的地址列表,通过addressEntries ()获得这个列表。
//QNetworkAddressEntry包含了一个网络接口的IP地址、子网掩码和广播地址,分别用ip()、netmask()和broadcast()函数返回。
for(int i=0;i<list.count();i++)
{
QNetworkInterface aInterface=list.at(i);
if(!aInterface.isValid())
{
continue;
}
QList<QNetworkAddressEntry> entryList=aInterface.addressEntries();
for(int j=0;j<entryList.count();j++)
{
QNetworkAddressEntry aEntry=entryList.at(j);
ui->plainTextEdit->appendPlainText("IP地址:"+aEntry.ip().toString());
ui->plainTextEdit->appendPlainText("子网掩码:"+aEntry.netmask().toString());
ui->plainTextEdit->appendPlainText("广播地址:"+aEntry.broadcast().toString()+"\n");
}
ui->plainTextEdit->appendPlainText("\n");
}
}
void Form::on_btnLookUp_clicked()
{
QString hostname=ui->editHost->text();
ui->plainTextEdit->appendPlainText("正在查询主机信息:"+hostname);
QHostInfo::lookupHost(hostname,this,SLOT(lookedUpHostInfo(const QHostInfo &)));
}
1.2 代码详解
- 通过静态函数QHostInfo::localHostName()获取本机主机名hostName,然后再使用主机名作为参数,用静态函数QHostInfo::fromName(hostName)获取主机的信息hostInfo。
hostInfo是QHostInfo类的实例,通过其函数addresses()获取主机的IP地址列表。
QList addList=hostInfo.addresses();返回的addList是QHostAddress类的列表,QHostAddress类提供一个IP地址的信息,包括IPv4地址和IPv6地址。QHostAddress有以下两个主要的函数。
protocol() 返回QAbstractSocket::NetworkLayerProtocol类型变量,表示当前IP地址的协议类型。QAbstractSocket::NetworkLayerProtocol枚举类型的取值。
aHost.toString () 返回IP地址的字符串,表示程序中显示了IP地址列表中每个IP地址的协议类型和IP地址字符串,为根据protocol()返回的QAbstractSocket::NetworkLayerProtocol枚举值显示协议名称字符串,自定义了一个函数protocolName(),代码如下:QString Form::protocolName(QAbstractSocket::NetworkLayerProtocol protocol)
“主机名和IP地址"按钮,如果勾选了“只显示 IPv4协议地址”复选框,就只显示本机的IPv4地址,否则显示所有IP地址信息。 - 查找主机地址信息
QHostInfo的静态函数lookupHost()可以根据主机名、域名或IP地址查找主机的地址信息,lookupHost()函数原型如下:int QHostInfo::lookupHost(const QString &name, QObject *receiver, const char *member)输入参数name是表示主机名的字符串,可以是一个主机名、一个域名,或者是一个IP地址。
lookupHost()以异步方式查找主机地址,参数receiver和member指定一个响应槽函数的接收者和槽函数名称。执行lookupHost()后,程序可能需要花一定时间来查找主机地址,但不会阻塞程序的运行。当查找到主机地址后,通过信号通知设定的槽函数,在槽函数里读取查找的结果。函数返回一个表示查找的ID。
二、主机信息
查询一个主机的MAC地址或IP地址是网络应用程序中经常用到的功能,Qt提供了QHostInfo和QNetworkInterface类可以用于此类信息的查询。
QHostInfo的静态函数localHostName()可获取本机的主机名,静态函数fromName()可以通过主机名获取IP地址,静态函数lookupHost()可以通过一个主机名,以异步方式查找这个主机的IP地址。
QHostInfo类的主要函数如下
QNetworkInterface可以获得运行应用程序的主机的所有IP地址和网络接口列表。静态函数allInterfaces()返回主机上所有的网络接口的列表,一个网络接口可能包括多个的IP地址,每个IP地址与掩码或广播地址关联。如果无需知道子网掩码和广播的IP地址,使用静态函数allAddresses()可以获得主机上的所有IP地址列表。下表是QNetworkInterface类的主要功能函数。