天天看點

《QT5.9 c++ 開發指南》第14章 網絡程式設計(QHostInfo QNetworkInterface)

      Qt 網絡子產品提供了用于編寫 TCP/IP 客戶 端和伺服器端程式的各種類,如用于 TCP 通信的QTcpSocket 和 QTcpServe r ,用 于 UDP 通信的 QUdpSocket , 還有用于實作 HTTP 、 FTP 等普通網絡協定的進階類如 QNetworkReq uest, QNetworkReply 和 QNetworkAccessManager c Qt 網絡子產品還提供用于網絡代理 、 網絡承載管理的類,提供基于安全套接宇層( Secure Sockets Layer , SSL )協定的安全網絡通信的類 。

      要想運用此子產品,必須工程中加上:  QT += network   

      不然程式無法找到對應的檔案。

      話不多說,先上圖:

《QT5.9 c++ 開發指南》第14章 網絡程式設計(QHostInfo QNetworkInterface)
《QT5.9 c++ 開發指南》第14章 網絡程式設計(QHostInfo QNetworkInterface)
《QT5.9 c++ 開發指南》第14章 網絡程式設計(QHostInfo QNetworkInterface)

對應的頭檔案:

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QHostInfo>  //必須加上 .pro   QT       += network

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog();

private slots:
    void lookedUpHostInfo(const QHostInfo &host);
    /************************************************/
    void on_btnGetHostInfo_clicked();

    void on_btnDetail_clicked();

    void on_btnALLInterface_clicked();

    void on_btnLookup_clicked();

    void on_btnClear_clicked();

private:
    Ui::Dialog *ui;

    QString  protocolName(QAbstractSocket::NetworkLayerProtocol protocol); //
};

#endif // DIALOG_H
           

對應的cpp檔案:

#include "dialog.h"
#include "ui_dialog.h"


#include    <QHostInfo>
#include    <QNetworkInterface>

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
}

Dialog::~Dialog()
{
    delete ui;
}

void Dialog::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->chkOnlyIPv4->isChecked();//隻顯示IPv4
            if(show)
            {
                show = (QAbstractSocket::IPv4Protocol == ahost.protocol());
            }
            else {
                show = true;
            }
            if(show)
            {
                ui->plainTextEdit->appendPlainText("協 議:"+protocolName(ahost.protocol()));
                ui->plainTextEdit->appendPlainText(ahost.toString());
            }
        }
    }

}

void Dialog::on_btnGetHostInfo_clicked()
{
    //QHostInfo擷取主機資訊
    QString hostName = QHostInfo::localHostName();//本地主機名
    ui->plainTextEdit->appendPlainText("本機主機名:"+hostName+"\n");
    QHostInfo hostInfo = QHostInfo::fromName(hostName); //本機IP位址

    QList<QHostAddress> addList = hostInfo.addresses();//IP位址清單

    if(!addList.isEmpty())
    {
        for (int i = 0; i<addList.count();i++)
        {
            QHostAddress aHost = addList.at(i);//每一項是一個QHostAddress
            bool show = ui->chkOnlyIPv4->isChecked();//隻顯示IPv4
            if(show){
                show = (QAbstractSocket::IPv4Protocol == aHost.protocol());
            }
            else {
                show = true;
            }
            if(show)
            {
                ui->plainTextEdit->appendPlainText("協定:"+protocolName(aHost.protocol()));
                ui->plainTextEdit->appendPlainText("本機IP位址:"+aHost.toString()); //IP位址
                ui->plainTextEdit->appendPlainText("");
            }
        }
    }

}

void Dialog::on_btnDetail_clicked()
{
   //QNetworkInterface::allAddresses()的使用
    QList<QHostAddress> addList  =  QNetworkInterface::allAddresses();
    if(!addList.isEmpty())
    {
        for (int i = 0; i<addList.count();i++)
        {
            QHostAddress aHost = addList.at(i);//每一項是一個QHostAddress
            bool show = ui->chkOnlyIPv4->isChecked();//隻顯示IPv4
            if(show){
                show = (QAbstractSocket::IPv4Protocol == aHost.protocol());
            }
            else {
                show = true;
            }
            if(show)
            {
                ui->plainTextEdit->appendPlainText("協定:"+protocolName(aHost.protocol()));
                ui->plainTextEdit->appendPlainText("本機IP位址:"+aHost.toString()); //IP位址
                ui->plainTextEdit->appendPlainText("");
            }
        }
    }
}

void Dialog::on_btnALLInterface_clicked()
{
    //QNetworkInterface::allInterfaces()函數的使用
    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 Dialog::on_btnLookup_clicked()
{
    //查找主機資訊
    QString hostname = ui->editHost->text();
    ui->plainTextEdit->appendPlainText("正在查找查找主機資訊:"+hostname);
    QHostInfo::lookupHost(hostname,this,SLOT(lookedUpHostInfo(QHostInfo)));
}

void Dialog::on_btnClear_clicked()
{
   ui->plainTextEdit->clear();
}

QString Dialog::protocolName(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 "Unknown Network Layer Protocol";
    }
}
           

對于裡面的知識點這裡詳細解說:

1.on_btnGetHostInfo_clicked()  函數為 “擷取本機主機名和 IP 位址” 按鈕對應的函數:

         這段代碼先通過靜态函數 QHostlnfo: : localHostName()擷取本機主機名 hostName , 然後再使用主機名作為參數,用靜态函數 QHostlnfo::fromName(hostName)擷取主機的資訊 hostlnfo。

          傳回的 addList 是 QHostAddress 類的清單 , QHostAddress 類提供一個 IP 位址的資訊,包括 IPv4位址和 IPv6 位址 。

          QHostAddress 有兩個常用的成員函數:

  • protocol()傳回 QAbstractSocket::NetworkLayerProtoco l 類型變量 , 表示目前 IP 位址的協定類型。
  • toString ()傳回 IP 位址的字元串 , 表示程式中顯示了 IP 位址清單中每個 IP 位址的協定類型和 IP 位址宇符串

    為根據 protocol()傳回的 QAbstractSocket::NetworkLayerProtocol 枚舉值顯示協定名稱字元串,自定義了 一個函數 :

protocolName(QAbstractSocket::NetworkLayerProtocol protocol)

2.通過主機來查找。

QHostlnfo 的 靜态 函數 lookupHost()可 以根據 主機名 、域名或 IP 位址查找主機的位址資訊

on_btnLookup_clicked() 函數裡面運用這個方法

QHostInfo::lookupHost(hostname,this,SLOT(lookedUpHostInfo(QHostInfo)));

調用  lookedUpHostInfo(const QHostInfo &host)  自定義函數。

3.QNetworklnterface

      QNetworklnterface 可 以獲得應用程式所在主機的所有網絡接口 , 包括其子網路遮罩和廣播位址等。靜态函數 QNetworkinterface : :alllnterfaces()擷取所有網絡接口的清單。

on_btnALLInterface_clicked()  函數裡使用了這個方法。

        通過 QNetworklnterface: :alllnterfaces()擷取網絡接口清單 list 之後 ,顯示每個接口的 humanReadableName()和 hardwareAddress() 。每個接 口 又有 一個 QNetwork.AddressEntry 類型的位址清單,通過addressEntries ()獲得這個清單。

        QNetworkAddressEntry 包含了 一個網 絡接 口的 IP 位址、 子網路遮罩和廣播位址,分别用 ip()、netmask()和 broadcast()函 數傳回。

4.通過QNetworkl nterface::allInterfaces()傳回的網絡接口的資訊很多,如果無需知道子網路遮罩和廣播位址等資訊

 傳回的結果與 1中的處理方式一樣。

繼續閱讀