Qt获取网络接口信息

 Qt Widgets
时间:

QHostInfo

在建立网络连接之前,QTcpSocket和QUdpSocket执行一个名称查找,将所连接的主机名转换为一个IP地址。此操作通常使用DNS(域名服务)协议执行。
QHostInfo提供了一个静态函数,允许您自己执行此类查找。通过使用主机名、QObject指针和槽签名调用QHostInfo::lookupHost(), QHostInfo将执行名称查找,并在结果准备好时调用给定槽。实际的查找是在单独的线程中完成的,使用操作系统自己的方法来执行名称查找。
QHostInfo还提供了一个名为QHostInfo::fromName()的静态函数,它接受主机名作为参数并返回结果。在这种情况下,名称查找在与调用者相同的线程中执行。此重载对于非gui应用程序或在单独的非gui线程中进行名称查找非常有用。(在GUI线程中调用此函数可能会导致用户界面冻结,而函数在执行查找时阻塞。)

QNetworkInterface

QNetworkInterface表示连接到运行程序的主机的一个网络接口。每个网络接口可以包含零个或多个IP地址,每个IP地址可选地与一个网络掩码和/或一个广播地址相关联。可以通过addressEntries()获得这类三元组的列表。另外,当不需要网掩码或广播地址或其他信息时,使用alladdress()便利函数只获取活动接口的IP地址。
QNetworkInterface还使用hardwareAddress()报告接口的硬件地址。
并非所有操作系统都支持报告所有特性。在所有平台中,只有IPv4地址被这个类保证列出。特别地,IPv6地址列表只支持Windows, Linux, macOS和BSDs。

实践案例

catnetwork.h

#ifndef CATNETWORK_H
#define CATNETWORK_H

#include <QObject>

class QHostInfo;

class CatNetWork : public QObject
{
    Q_OBJECT
    Q_ENUMS(IP)
public:
    explicit CatNetWork(QObject *parent = nullptr);
    ~CatNetWork();

public:
    enum IP {
        V4,
        V6
    };
    void lookupHost(QString host);

    // 获取当前系统 所有可用的Ipv4地址
    QList<QString> GetAllIpaddressIpv4( void ) const;
    // 获取当前系统 所有可用的Ipv6地址
    QList<QString> GetAllIpaddressIpv6( void ) const;
    // 获取当前系统 所有可用的网络设备名
    QList<QString> GetAllNetWorkName( void ) const;
    // 根据 网络设备名获取MAC地址
    QString GetNetWorkHardware(QString name);
    // 根据 IP获取MAC地址
    QString GetNetWorkHardware(QString ipaddress, IP ip);
    // 根据 IP获取广播地址
    QString GetNetWorkBroadcast(QString ipaddress, IP ip);
    // 根据 IP获取网络掩码
    QString GetNetWorkNetMask(QString ipaddress, IP ip);

private:
    struct NETWORKADDRESSENTRY {
        QString IpAddressV4;
        QString IpAddressV6;
        QString NetMask;
        QString Broadcast;
    };

    struct NETWORKINTERFACE {
        QString Name;
        QString Hardware;
        QList<NETWORKADDRESSENTRY> Entry;
    };

    void InitNetworkInterface( void );

signals:
    void LookupHost(QString host);
    void update_NetWorkIpv4(QList<QString>);
    void update_NetWorkIpv6(QList<QString>);

private slots:
    void Update_NetworkInterface( void );

    //void lookedUp(const QHostInfo &host);

private:
    QList<NETWORKINTERFACE> m_lNetworkimterface;
    QList<QString> m_lIpaddressIpv4;
    QList<QString> m_lIpaddressIpv6;
    QList<QString> m_lName;
};

#endif // CATNETWORK_H

catnetwork.cpp

#include "catnetwork.h"
#include <QHostInfo>
#include <QNetworkInterface>

CatNetWork::CatNetWork(QObject *parent)
    : QObject(parent)
{
    Update_NetworkInterface();
}

CatNetWork::~CatNetWork()
{

}

void CatNetWork::lookupHost(QString host)
{
    QHostInfo::lookupHost(host, this, [=](const QHostInfo &host){
        if(host.error() != QHostInfo::NoError)
        {
            emit LookupHost(host.errorString());
        }

        foreach(const QHostAddress &address, host.addresses())
        {
            emit LookupHost(address.toString());
        }

    });

}

QList<QString> CatNetWork::GetAllIpaddressIpv4() const
{
    return m_lIpaddressIpv4;
}

QList<QString> CatNetWork::GetAllIpaddressIpv6() const
{
    return m_lIpaddressIpv6;
}



QList<QString> CatNetWork::GetAllNetWorkName() const
{
    return m_lName;
}

QString CatNetWork::GetNetWorkHardware(QString name)
{
    QString hardware = "";

    for(auto temp : m_lNetworkimterface)
    {
        if(temp.Name == name)
        {
            hardware = temp.Hardware;
        }
    }

    return hardware;
}

QString CatNetWork::GetNetWorkHardware(QString ipaddress, CatNetWork::IP ip)
{
    QString hardware = "";
    for(auto temp : m_lNetworkimterface)
    {
        for(auto tempentry : temp.Entry)
        {
            if(ip == CatNetWork::IP::V4 && ipaddress == tempentry.IpAddressV4)
            {
                hardware = temp.Hardware;
            } else if(ip == CatNetWork::IP::V6 && ipaddress == tempentry.IpAddressV6)
            {
                hardware = temp.Hardware;
            }
        }
    }
    return hardware;
}

QString CatNetWork::GetNetWorkBroadcast(QString ipaddress, CatNetWork::IP ip)
{
    QString broadcast = "";
    for(auto temp : m_lNetworkimterface)
    {
        for(auto tempentry : temp.Entry)
        {
            if(ip == CatNetWork::IP::V4 && ipaddress == tempentry.IpAddressV4)
            {
                broadcast = tempentry.Broadcast;
            } else if(ip == CatNetWork::IP::V6 && ipaddress == tempentry.IpAddressV6)
            {
                broadcast = tempentry.Broadcast;
            }
        }
    }
    return broadcast;
}

QString CatNetWork::GetNetWorkNetMask(QString ipaddress, CatNetWork::IP ip)
{
    QString netmask = "";
    for(auto temp : m_lNetworkimterface)
    {
        for(auto tempentry : temp.Entry)
        {
            if(ip == CatNetWork::IP::V4 && ipaddress == tempentry.IpAddressV4)
            {
                netmask = tempentry.NetMask;
            } else if(ip == CatNetWork::IP::V6 && ipaddress == tempentry.IpAddressV6)
            {
                netmask = tempentry.NetMask;
            }
        }
    }
    return netmask;
}

void CatNetWork::InitNetworkInterface()
{
    // 获取所有网络接口的列表
    QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();
    // 遍历每一个网络接口
    foreach(QNetworkInterface interface, list)
    {
        NETWORKINTERFACE temp;
        // 接口名
        temp.Name = interface.name();
        m_lName.push_back(temp.Name);

        // 硬件地址
        temp.Hardware = interface.hardwareAddress();

        // 获取IP地址条目列表,每个条目包含一个IP地址,子网掩码和广播地址
        QList<QNetworkAddressEntry> entryList = interface.addressEntries();

        foreach(QNetworkAddressEntry entry, entryList)
        {
            NETWORKADDRESSENTRY EntryTemp;
            // IP 地址
            QString ip = entry.ip().toString();
            if(!ip.isEmpty())
            {
                if(entry.ip().protocol() == QAbstractSocket::IPv4Protocol)
                {
                    EntryTemp.IpAddressV6 = "";
                    EntryTemp.IpAddressV4 = ip;
                    m_lIpaddressIpv4.push_back(EntryTemp.IpAddressV4);
                } else if(entry.ip().protocol() == QAbstractSocket::IPv6Protocol) {
                    EntryTemp.IpAddressV4 = "";
                    EntryTemp.IpAddressV6 = ip;
                    m_lIpaddressIpv6.push_back(EntryTemp.IpAddressV6);
                }
            }
            // 子网掩码
            EntryTemp.NetMask = entry.netmask().toString();
            // 广播地址
            EntryTemp.Broadcast = entry.broadcast().toString();

            temp.Entry.push_back(EntryTemp);
        }

        m_lNetworkimterface.push_back(temp);
    }

}

void CatNetWork::Update_NetworkInterface()
{
    m_lNetworkimterface.clear();
    m_lName.clear();
    m_lIpaddressIpv4.clear();
    m_lIpaddressIpv6.clear();
    InitNetworkInterface();
    emit update_NetWorkIpv4(m_lIpaddressIpv4);
    emit update_NetWorkIpv6(m_lIpaddressIpv6);
}

main.cpp

#include <QCoreApplication>
#include <QtNetwork>
#include <QHostInfo>
#include <QDebug>
#include "catnetwork.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    CatNetWork network;
    QObject::connect(&network, &CatNetWork::LookupHost, &network, [=](QString host){
        qDebug() << "Host: " << host;
    });
    QObject::connect(&network, &CatNetWork::update_NetWorkIpv4, &network, [=](QList<QString> list){
        qDebug() << "Ipv4: " << list;
    });
    QObject::connect(&network, &CatNetWork::update_NetWorkIpv6, &network, [=](QList<QString> list){
        qDebug() << "Ipv6: " << list;
    });
    network.lookupHost("www.graycatya.com");

    qDebug() << network.GetNetWorkHardware(network.GetAllIpaddressIpv4()[1], CatNetWork::V4);
    qDebug() << network.GetNetWorkBroadcast(network.GetAllIpaddressIpv4()[1], CatNetWork::V4);
    qDebug() << network.GetNetWorkNetMask(network.GetAllIpaddressIpv4()[1], CatNetWork::V4);

    network.Update_NetworkInterface();

    return a.exec();
}

1 评论