• 十四、Qt主机信息与网络编程


    一、主机信息

    1、主机信息接口

    • QHostInfo:获取主机名称和IP地址
    • QNetWorkInterface:获取主机的所有网络接口,包括子网掩码和广播地址等

    (1)使用

    项目添加模块
    
    • 1
    QT       += network
    
    • 1

    2、实现程序

    在这里插入图片描述

    (1)创建项目,基于QDialog

    在这里插入图片描述

    (2)实现功能

    #ifndef DIALOG_H
    #define DIALOG_H
    
    #include 
    
    #include 
    #include 
    
    namespace Ui
    {
    class Dialog;
    }
    
    class Dialog : public QDialog
    {
        Q_OBJECT
    
    private:
        QString protocolName(QAbstractSocket::NetworkLayerProtocol protocol);
    
    public:
        explicit Dialog(QWidget *parent = nullptr);
        ~Dialog();
    
    private slots:
        void on_btnHostIP_clicked();
    
        void on_btnClearText_clicked();
    
        void on_btnDnsIP_clicked();
    
        void on_lookUpHostInfo(QHostInfo host);
    
        void on_btnAllAddresses_clicked();
    
        void on_btnAllInterface_clicked();
    
    private:
        Ui::Dialog *ui;
    };
    
    #endif // DIALOG_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    #include "dialog.h"
    #include "ui_dialog.h"
    
    
    
    QString Dialog::protocolName(QAbstractSocket::NetworkLayerProtocol protocol)
    {
        switch (protocol)
        {
        case QAbstractSocket::IPv4Protocol:
            return "IPv4 Protocol";
            break;
        case QAbstractSocket::IPv6Protocol:
            return "IPv6 Protocol";
            break;
        case QAbstractSocket::AnyIPProtocol:
            return "AnyIP Protocol";
            break;
        default:
            return "Unknown Protocol";
            break;
        }
    }
    
    Dialog::Dialog(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::Dialog)
    {
        ui->setupUi(this);
    }
    
    Dialog::~Dialog()
    {
        delete ui;
    }
    
    void Dialog::on_btnHostIP_clicked()
    {
        QString hostName = QHostInfo::localHostName();
        ui->plainTextEdit->appendPlainText(hostName);
    
        QHostInfo hostInfo = QHostInfo::fromName(hostName);
        QList<QHostAddress> addList = hostInfo.addresses();
        foreach (auto aHost, addList)
        {
            if(ui->checkBox->isChecked())
            {
                if(aHost.protocol() == QAbstractSocket::IPv4Protocol)
                {
                    ui->plainTextEdit->appendPlainText("协议:" + protocolName(aHost.protocol()));
                    ui->plainTextEdit->appendPlainText("本机IP地址:" + aHost.toString());
                    ui->plainTextEdit->appendPlainText("");
                }
            }
            else
            {
                ui->plainTextEdit->appendPlainText("协议:" + protocolName(aHost.protocol()));
                ui->plainTextEdit->appendPlainText("本机IP地址:" + aHost.toString());
                ui->plainTextEdit->appendPlainText("");
            }
        }
    }
    
    void Dialog::on_btnClearText_clicked()
    {
        ui->plainTextEdit->clear();
    }
    
    void Dialog::on_btnDnsIP_clicked()
    {
        // 异步方式
        QString hostName = ui->lineEdit->text();
        ui->plainTextEdit->appendPlainText("正在查询主机信息:" + hostName);
        QHostInfo::lookupHost(hostName, this, SLOT(on_lookUpHostInfo(QHostInfo)));
    }
    
    void Dialog::on_lookUpHostInfo(QHostInfo host)
    {
        QList<QHostAddress> addList = host.addresses();
        foreach (auto aHost, addList)
        {
            if(ui->checkBox->isChecked())
            {
                if(aHost.protocol() == QAbstractSocket::IPv4Protocol)
                {
                    ui->plainTextEdit->appendPlainText("协议:" + protocolName(aHost.protocol()));
                    ui->plainTextEdit->appendPlainText("IP地址:" + aHost.toString());
                    ui->plainTextEdit->appendPlainText("");
                }
            }
            else
            {
                ui->plainTextEdit->appendPlainText("协议:" + protocolName(aHost.protocol()));
                ui->plainTextEdit->appendPlainText("IP地址:" + aHost.toString());
                ui->plainTextEdit->appendPlainText("");
            }
        }
    }
    
    void Dialog::on_btnAllAddresses_clicked()
    {
        QList<QHostAddress> addList = QNetworkInterface::allAddresses();
        foreach (auto aHost, addList)
        {
            if(ui->checkBox->isChecked())
            {
                if(aHost.protocol() == QAbstractSocket::IPv4Protocol)
                {
                    ui->plainTextEdit->appendPlainText("协议:" + protocolName(aHost.protocol()));
                    ui->plainTextEdit->appendPlainText("IP地址:" + aHost.toString());
                    ui->plainTextEdit->appendPlainText("");
                }
            }
            else
            {
                ui->plainTextEdit->appendPlainText("协议:" + protocolName(aHost.protocol()));
                ui->plainTextEdit->appendPlainText("IP地址:" + aHost.toString());
                ui->plainTextEdit->appendPlainText("");
            }
        }
    }
    
    void Dialog::on_btnAllInterface_clicked()
    {
        QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();
        foreach (auto aInterface, list)
        {
            if(!aInterface.isValid())
            {
                continue;
            }
            ui->plainTextEdit->appendPlainText("设备名称: " + aInterface.humanReadableName());
            ui->plainTextEdit->appendPlainText("硬件地址: " + aInterface.hardwareAddress());
            QList<QNetworkAddressEntry> entryList = aInterface.addressEntries();
            foreach (auto aEntry, entryList)
            {
                ui->plainTextEdit->appendPlainText("  IP地址: " + aEntry.ip().toString());
                ui->plainTextEdit->appendPlainText("  子网掩码: " + aEntry.netmask().toString());
                ui->plainTextEdit->appendPlainText("  广播地址: " + aEntry.broadcast().toString());
            }
            ui->plainTextEdit->appendPlainText("");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144

    在这里插入图片描述

    二、TCP通信

    TCP是一种被大多数Internet网络协议(HTTP、FTP等)用于数据传输的低级网络协议,是可靠的、面向流、面向连接的传输协议。
    
    • 1

    1、相关类

    (1)继承关系

    QIODevice
    	QAbstractSocket
    		QTcpSocket
    			QSctpSocket
    			QSslSocket // 加密
    		QUdpSocket			
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、实现服务端程序

    在这里插入图片描述

    (1)创建项目

    (2)添加图标资源

    在这里插入图片描述

    (3)实现服务器功能

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include 
    #include 
    #include 
    #include 
    
    namespace Ui
    {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    private:
        QLabel *labListen;
        QLabel *labSocketState;
    
        QTcpServer *tcpServer;
        QTcpSocket *tcpSocket;
    
    public:
        explicit MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    protected:
        void closeEvent(QCloseEvent *event);
    
    private:
        QString getLocalIP();
    
    private slots:
        void on_newConnection();
    
        void on_clientConnected();
    
        void on_clientDisconnected();
    
        void on_clientStateChanged(QAbstractSocket::SocketState state);
    
        void on_clientReadyRead();
    
        void on_actStartListen_triggered();
    
        void on_actStopListen_triggered();
    
        void on_actClearText_triggered();
    
        void on_btnSend_clicked();
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include 
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        labListen = new QLabel("监听状态:");
        labListen->setMinimumWidth(200);
        labSocketState = new QLabel("Socket状态:");
        labSocketState->setMinimumWidth(200);
        ui->statusBar->addWidget(labListen);
        ui->statusBar->addWidget(labSocketState);
    
        setWindowTitle("服务器:" + getLocalIP());
    
        tcpServer = new QTcpServer(this);
    
        connect(tcpServer, SIGNAL(newConnection()),
                this, SLOT(on_newConnection()));
    
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::closeEvent(QCloseEvent *event)
    {
        if(tcpServer->isListening())
        {
            tcpServer->close();
        }
        event->accept();
    }
    
    QString MainWindow::getLocalIP()
    {
        QString hostName = QHostInfo::localHostName();
        QHostInfo hostInfo = QHostInfo::fromName(hostName);
        QString loaclIP;
        QList<QHostAddress> addList = hostInfo.addresses();
        foreach (auto aHost, addList)
        {
            if(aHost.protocol() == QAbstractSocket::IPv4Protocol)
            {
                if(loaclIP.isEmpty())
                {
                    loaclIP = aHost.toString();
                }
                ui->comboBoxAddresses->addItem(aHost.toString());
            }
        }
        return loaclIP;
    }
    
    void MainWindow::on_newConnection()
    {
        tcpSocket = tcpServer->nextPendingConnection(); //获取socket
        connect(tcpSocket, SIGNAL(connected()), this, SLOT(on_clientConnected()));
        on_clientConnected(); //当前状态已经发送,需要直接调用通知
        connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(on_clientDisconnected()));
        connect(tcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
                this, SLOT(on_clientStateChanged(QAbstractSocket::SocketState)));
        on_clientStateChanged(tcpSocket->state()); //当前状态已经发送,需要直接调用通知
    
        connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(on_clientReadyRead()));
    
    }
    
    void MainWindow::on_clientConnected()
    {
        ui->plainTextEdit->appendPlainText("**client socket connected");
        ui->plainTextEdit->appendPlainText("**peer address: " + tcpSocket->peerAddress().toString());
        ui->plainTextEdit->appendPlainText("**peer port " + QString::number(tcpSocket->peerPort()));
    }
    
    void MainWindow::on_clientDisconnected()
    {
        ui->plainTextEdit->appendPlainText("**client socket disconnected");
        tcpSocket->deleteLater();
    }
    
    void MainWindow::on_clientStateChanged(QAbstractSocket::SocketState state)
    {
        switch (state)
        {
        case QAbstractSocket::UnconnectedState:
            labSocketState->setText("socket状态:UnconnectedState");
            break;
        case QAbstractSocket::HostLookupState:
            labSocketState->setText("socket状态:HostLookupState");
            break;
        case QAbstractSocket::ConnectingState:
            labSocketState->setText("socket状态:ConnectingState");
            break;
        case QAbstractSocket::ConnectedState:
            labSocketState->setText("socket状态:ConnectedState");
            break;
        case QAbstractSocket::BoundState:
            labSocketState->setText("socket状态:BoundState");
            break;
        case QAbstractSocket::ListeningState:
            labSocketState->setText("socket状态:ListeningState");
            break;
        case QAbstractSocket::ClosingState:
            labSocketState->setText("socket状态:ClosingState");
            break;
        default:
            break;
        }
    }
    
    void MainWindow::on_clientReadyRead()
    {
        //    while(tcpSocket->canReadLine())
        int nLen = 0;
        do
        {
            char data[1024] = {0};
            nLen = tcpSocket->readLine(data, 1023);
            if(nLen > 0)
            {
                ui->plainTextEdit->appendPlainText(QString::asprintf("[in]: %s", data));
            }
        } while(nLen > 0);
    }
    
    void MainWindow::on_actStartListen_triggered()
    {
        QString IP = ui->comboBoxAddresses->currentText();
        int port = ui->spinBoxPort->value();
    
        QHostAddress addr(IP);
        tcpServer->listen(addr, port);
    
        ui->plainTextEdit->appendPlainText("**开始监听");
        ui->plainTextEdit->appendPlainText("**服务IP:" + tcpServer->serverAddress().toString());
        ui->plainTextEdit->appendPlainText("**服务器端口:" + QString::number(tcpServer->serverPort()));
    
        ui->actStartListen->setEnabled(false);
        ui->actStopListen->setEnabled(true);
        labListen->setText("监听状态:开始");
    }
    
    void MainWindow::on_actStopListen_triggered()
    {
        if(tcpServer->isListening())
        {
            tcpServer->close();
            ui->actStartListen->setEnabled(true);
            ui->actStopListen->setEnabled(false);
            labListen->setText("监听状态:停止");
        }
    }
    
    void MainWindow::on_actClearText_triggered()
    {
        ui->plainTextEdit->clear();
    }
    
    void MainWindow::on_btnSend_clicked()
    {
        QString msg = ui->lineEdit->text();
        ui->plainTextEdit->appendPlainText("[out] " + msg);
        ui->lineEdit->clear();
        ui->lineEdit->setFocus();
    
        msg += "\n";
        QByteArray data = msg.toUtf8();
    
        tcpSocket->write(data);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180

    3、实现客户端程序

    在这里插入图片描述

    (1)创建项目

    (2)添加图标资源

    在这里插入图片描述

    (3)实现功能

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include 
    #include 
    #include 
    #include 
    
    
    namespace Ui
    {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    private:
        QLabel *labSocketState;
    
        QTcpSocket *tcpSocket;
    
    public:
        explicit MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    private:
        QString getLocalIP();
    
    private slots:
        void on_Connected();
    
        void on_Disconnected();
    
        void on_StateChanged(QAbstractSocket::SocketState state);
    
        void on_ReadyRead();
    
        void on_btnSend_clicked();
    
        void on_actConnect_triggered();
    
        void on_actDisconnect_triggered();
    
        void on_actClear_triggered();
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include 
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        labSocketState = new QLabel("Socket状态:");
        labSocketState->setMinimumWidth(200);
        ui->statusBar->addWidget(labSocketState);
    
        setWindowTitle("客户端:" + getLocalIP());
    
        tcpSocket = new QTcpSocket;
        connect(tcpSocket, SIGNAL(connected()), this, SLOT(on_Connected()));
        connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(on_Disconnected()));
        connect(tcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
                this, SLOT(on_StateChanged(QAbstractSocket::SocketState)));
        connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(on_ReadyRead()));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    QString MainWindow::getLocalIP()
    {
        QString hostName = QHostInfo::localHostName();
        QHostInfo hostInfo = QHostInfo::fromName(hostName);
        QString loaclIP;
        QList<QHostAddress> addList = hostInfo.addresses();
        foreach (auto aHost, addList)
        {
            if(aHost.protocol() == QAbstractSocket::IPv4Protocol)
            {
                if(loaclIP.isEmpty())
                {
                    loaclIP = aHost.toString();
                }
                ui->comboBox->addItem(aHost.toString());
            }
        }
        return loaclIP;
    }
    
    void MainWindow::on_Connected()
    {
        ui->plainTextEdit->appendPlainText("**socket connected");
        ui->plainTextEdit->appendPlainText("**peer address: " + tcpSocket->peerAddress().toString());
        ui->plainTextEdit->appendPlainText("**peer port " + QString::number(tcpSocket->peerPort()));
    }
    
    void MainWindow::on_Disconnected()
    {
        ui->plainTextEdit->appendPlainText("**socket disconnected");
    }
    
    void MainWindow::on_StateChanged(QAbstractSocket::SocketState state)
    {
        switch (state)
        {
        case QAbstractSocket::UnconnectedState:
            labSocketState->setText("socket状态:UnconnectedState");
            break;
        case QAbstractSocket::HostLookupState:
            labSocketState->setText("socket状态:HostLookupState");
            break;
        case QAbstractSocket::ConnectingState:
            labSocketState->setText("socket状态:ConnectingState");
            break;
        case QAbstractSocket::ConnectedState:
            labSocketState->setText("socket状态:ConnectedState");
            break;
        case QAbstractSocket::BoundState:
            labSocketState->setText("socket状态:BoundState");
            break;
        case QAbstractSocket::ListeningState:
            labSocketState->setText("socket状态:ListeningState");
            break;
        case QAbstractSocket::ClosingState:
            labSocketState->setText("socket状态:ClosingState");
            break;
        default:
            break;
        }
    }
    
    void MainWindow::on_ReadyRead()
    {
        int nLen = 0;
        do
        {
            char data[1024] = {0};
            nLen = tcpSocket->readLine(data, 1023);
            if(nLen > 0)
            {
                ui->plainTextEdit->appendPlainText(QString::asprintf("[in]: %s", data));
            }
        } while(nLen > 0);
    }
    
    void MainWindow::on_btnSend_clicked()
    {
        QString msg = ui->lineEdit->text();
        ui->plainTextEdit->appendPlainText("[out] " + msg);
        ui->lineEdit->clear();
        ui->lineEdit->setFocus();
    
        msg += "\n";
        QByteArray data = msg.toUtf8();
    
        tcpSocket->write(data);
    }
    
    void MainWindow::on_actConnect_triggered()
    {
        QString IP = ui->comboBox->currentText();
        int port = ui->spinBox->value();
        tcpSocket->connectToHost(IP, port);
    
        ui->actConnect->setEnabled(false);
        ui->actDisconnect->setEnabled(true);
    }
    
    void MainWindow::on_actDisconnect_triggered()
    {
        if(tcpSocket->state() == QAbstractSocket::ConnectedState)
        {
            tcpSocket->disconnectFromHost();
        }
    
        ui->actConnect->setEnabled(true);
        ui->actDisconnect->setEnabled(false);
    }
    
    void MainWindow::on_actClear_triggered()
    {
        ui->plainTextEdit->clear();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145

    在这里插入图片描述

    三、UDP通信

    UDP用户数据报协议,是轻量的、不可靠的、面向数据报、无连接的协议。
    
    • 1

    1、实现单播/广播程序

    在这里插入图片描述

    (1)创建项目

    (2)添加图标资源

    在这里插入图片描述

    (3)实现功能

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include 
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        labSocketState = new QLabel("Socket状态:");
        labSocketState->setMinimumWidth(200);
        ui->statusBar->addWidget(labSocketState);
    
        QString localIP = getLocalIP();
        setWindowTitle("Udp收发器:" + localIP);
    
        udpSocket = new QUdpSocket(this);
        connect(udpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
                this, SLOT(on_StateChanged(QAbstractSocket::SocketState)));
        connect(udpSocket, SIGNAL(readyRead()),
                this, SLOT(on_SocketReadyRead()));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    QString MainWindow::getLocalIP()
    {
        QString hostName = QHostInfo::localHostName();
        QHostInfo hostInfo = QHostInfo::fromName(hostName);
        QString loaclIP;
        QList<QHostAddress> addList = hostInfo.addresses();
        foreach (auto aHost, addList)
        {
            if(aHost.protocol() == QAbstractSocket::IPv4Protocol)
            {
                if(loaclIP.isEmpty())
                {
                    loaclIP = aHost.toString();
                }
                ui->comboBox->addItem(aHost.toString());
            }
        }
        return loaclIP;
    }
    
    void MainWindow::on_StateChanged(QAbstractSocket::SocketState state)
    {
        switch (state)
        {
        case QAbstractSocket::UnconnectedState:
            labSocketState->setText("socket状态:UnconnectedState");
            break;
        case QAbstractSocket::HostLookupState:
            labSocketState->setText("socket状态:HostLookupState");
            break;
        case QAbstractSocket::ConnectingState:
            labSocketState->setText("socket状态:ConnectingState");
            break;
        case QAbstractSocket::ConnectedState:
            labSocketState->setText("socket状态:ConnectedState");
            break;
        case QAbstractSocket::BoundState:
            labSocketState->setText("socket状态:BoundState");
            break;
        case QAbstractSocket::ListeningState:
            labSocketState->setText("socket状态:ListeningState");
            break;
        case QAbstractSocket::ClosingState:
            labSocketState->setText("socket状态:ClosingState");
            break;
        default:
            break;
        }
    }
    
    void MainWindow::on_SocketReadyRead()
    {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());
        QHostAddress peerAddr;
        unsigned short peerPort;
    
        udpSocket->readDatagram(datagram.data(), datagram.size(), &peerAddr, &peerPort);
    
        QString str = datagram.data();
        QString peer = "[From " + peerAddr.toString() + ":" + QString::asprintf("%d", peerPort) + "] ";
        ui->plainTextEdit->appendPlainText(peer  + str);
    }
    
    void MainWindow::on_actStart_triggered()
    {
        quint16 port = ui->spinBoxBindPort->value();
        if(udpSocket->bind(port))
        {
            ui->plainTextEdit->appendPlainText("**已绑定成功");
            ui->plainTextEdit->appendPlainText("**端口:" + QString::number(udpSocket->localPort()));
    
            ui->actStart->setEnabled(false);
            ui->actStop->setEnabled(true);
        }
    }
    
    void MainWindow::on_actStop_triggered()
    {
        udpSocket->abort();
        ui->actStart->setEnabled(true);
        ui->actStop->setEnabled(false);
        ui->plainTextEdit->appendPlainText("**已解除绑定");
    }
    
    void MainWindow::on_actClear_triggered()
    {
        ui->plainTextEdit->clear();
    }
    
    void MainWindow::on_pushButton_clicked()
    {
        // 单播
        QString targetIP = ui->comboBox->currentText();
        quint16 targetPort = ui->spinBoxPort->value();
        QHostAddress targetAddr(targetIP);
    
        QString msg = ui->lineEdit->text();
        QByteArray data = msg.toUtf8();
    
        udpSocket->writeDatagram(data, targetAddr, targetPort);
        ui->plainTextEdit->appendPlainText("[out] " + msg);
    
        ui->lineEdit->clear();
        ui->lineEdit->setFocus();
    }
    
    void MainWindow::on_pushButton_2_clicked()
    {
        // 广播
        quint16 targetPort = ui->spinBoxPort->value();
    
        QString msg = ui->lineEdit->text();
        QByteArray data = msg.toUtf8();
    
        udpSocket->writeDatagram(data, QHostAddress::Broadcast, targetPort);
        ui->plainTextEdit->appendPlainText("[out] " + msg);
    
        ui->lineEdit->clear();
        ui->lineEdit->setFocus();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151

    在这里插入图片描述

    2、实现组播程序

    在这里插入图片描述

    (1)拷贝上一个项目

    (2)修改控件

    在这里插入图片描述

    (3)实现功能

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        labSocketState = new QLabel("Socket状态:");
        labSocketState->setMinimumWidth(200);
        ui->statusBar->addWidget(labSocketState);
    
        QString localIP = getLocalIP();
        setWindowTitle("Udp组播收发器:" + localIP);
    
        udpSocket = new QUdpSocket(this);
        connect(udpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
                this, SLOT(on_StateChanged(QAbstractSocket::SocketState)));
        connect(udpSocket, SIGNAL(readyRead()),
                this, SLOT(on_SocketReadyRead()));
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    QString MainWindow::getLocalIP()
    {
        QString hostName = QHostInfo::localHostName();
        QHostInfo hostInfo = QHostInfo::fromName(hostName);
        QString loaclIP;
        QList<QHostAddress> addList = hostInfo.addresses();
        foreach (auto aHost, addList)
        {
            if(aHost.protocol() == QAbstractSocket::IPv4Protocol)
            {
                if(loaclIP.isEmpty())
                {
                    loaclIP = aHost.toString();
                }
                ui->comboBox->addItem(aHost.toString());
            }
        }
        return loaclIP;
    }
    
    void MainWindow::on_StateChanged(QAbstractSocket::SocketState state)
    {
        switch (state)
        {
        case QAbstractSocket::UnconnectedState:
            labSocketState->setText("socket状态:UnconnectedState");
            break;
        case QAbstractSocket::HostLookupState:
            labSocketState->setText("socket状态:HostLookupState");
            break;
        case QAbstractSocket::ConnectingState:
            labSocketState->setText("socket状态:ConnectingState");
            break;
        case QAbstractSocket::ConnectedState:
            labSocketState->setText("socket状态:ConnectedState");
            break;
        case QAbstractSocket::BoundState:
            labSocketState->setText("socket状态:BoundState");
            break;
        case QAbstractSocket::ListeningState:
            labSocketState->setText("socket状态:ListeningState");
            break;
        case QAbstractSocket::ClosingState:
            labSocketState->setText("socket状态:ClosingState");
            break;
        default:
            break;
        }
    }
    
    void MainWindow::on_SocketReadyRead()
    {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());
        QHostAddress peerAddr;
        unsigned short peerPort;
    
        udpSocket->readDatagram(datagram.data(), datagram.size(), &peerAddr, &peerPort);
    
        QString str = datagram.data();
        QString peer = "[From " + peerAddr.toString() + ":" + QString::asprintf("%d", peerPort) + "] ";
        ui->plainTextEdit->appendPlainText(peer  + str);
    }
    
    void MainWindow::on_actStart_triggered()
    {
        QString IP = ui->comboBox->currentText();
        groupAddress = QHostAddress(IP);
    
        quint16 groupPort = ui->spinBoxBindPort->value();
        if(udpSocket->bind(QHostAddress::AnyIPv4, groupPort, QUdpSocket::ShareAddress))
        {
            udpSocket->joinMulticastGroup(groupAddress);
            ui->plainTextEdit->appendPlainText("**加入组播成功");
            ui->plainTextEdit->appendPlainText("**组播IP:" + IP);
            ui->plainTextEdit->appendPlainText("**组播端口:" + QString::number(groupPort));
    
            ui->actStart->setEnabled(false);
            ui->actStop->setEnabled(true);
            ui->comboBox->setEnabled(false);
        }
        else
        {
            ui->plainTextEdit->appendPlainText("**端口绑定失败");
        }
    }
    
    void MainWindow::on_actStop_triggered()
    {
        udpSocket->leaveMulticastGroup(groupAddress);
    
        udpSocket->abort();
        ui->actStart->setEnabled(true);
        ui->actStop->setEnabled(false);
        ui->comboBox->setEnabled(true);
        ui->plainTextEdit->appendPlainText("**已退出组播,解除端口绑定");
    }
    
    void MainWindow::on_actClear_triggered()
    {
        ui->plainTextEdit->clear();
    }
    
    void MainWindow::on_btnSend_clicked()
    {
        QString targetIP = ui->comboBox->currentText();
        quint16 targetPort = ui->spinBoxBindPort->value();
        QHostAddress targetAddr(targetIP);
    
        QString msg = ui->lineEdit->text();
        QByteArray data = msg.toUtf8();
    
        udpSocket->writeDatagram(data, targetAddr, targetPort);
        ui->plainTextEdit->appendPlainText("[out] " + msg);
    
        ui->lineEdit->clear();
        ui->lineEdit->setFocus();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150

    在这里插入图片描述

    四、HTTP通信

    1、相关类

    QNetworkRequest,通过一个URL地址发起网络请求,也保存网络请求信息。
    QNetworkAccessManager,用于协调网络操作,在QNetworkRequest发起一个网络请求后,负责发送网络请求,创建网络响应。
    QNwtworkReply,网络请求的响应。
    
    • 1
    • 2
    • 3

    1、实现基于http协议文件下载

    在这里插入图片描述

    (1)创建项目

    在这里插入图片描述

    (2)实现功能

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include 
    #include 
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    #include 
    void MainWindow::on_finished()
    {
        QFileInfo fileInfo;
        fileInfo.setFile(downloadFile->fileName());
        downloadFile->close();
        delete downloadFile;
        downloadFile = nullptr;
        reply->deleteLater();
        reply = nullptr;
    
        if(ui->checkBox->isChecked())
        {
            QDesktopServices::openUrl(QUrl::fromLocalFile(fileInfo.absolutePath()));
            ui->btnDownload->setEnabled(true);
        }
    }
    
    void MainWindow::on_readyRead()
    {
        downloadFile->write(reply->readAll());
    }
    
    void MainWindow::on_downloadProgress(qint64 readBytes, qint64 totalBytes)
    {
        ui->progressBar->setMaximum(totalBytes);
        ui->progressBar->setValue(readBytes);
    }
    
    
    void MainWindow::on_btnDownload_clicked()
    {
        QString strUrl = ui->lineEditUrl->text();
        if(strUrl.isEmpty())
        {
            QMessageBox::information(this, "error", "请输入正确地址");
            return;
        }
    
        QUrl newUrl = QUrl::fromUserInput(strUrl);
        if(!newUrl.isValid())
        {
            QMessageBox::information(this, "error",
                                     QString::asprintf("无效的URL:%s\n错误信息: %s", strUrl.data(), newUrl.errorString().data()));
            return;
        }
    
        QString tempDir = ui->lineEditSavePath->text();
        if(tempDir.isEmpty())
        {
            QMessageBox::information(this, "error", "保存路径无效");
            return;
        }
    
        QString fullFileName = tempDir + newUrl.fileName();
        if(QFile::exists(fullFileName))
        {
            QFile::remove(fullFileName);
        }
    
        downloadFile = new QFile(fullFileName);
        if(!downloadFile->open(QIODevice::WriteOnly))
        {
            QMessageBox::information(this, "error", "文件打开失败:" + fullFileName);
            return;
        }
    
        ui->btnDownload->setEnabled(false);
        reply = networkManager.get(QNetworkRequest(newUrl));
        connect(reply, SIGNAL(finished()), this, SLOT(on_finished()));
        connect(reply, SIGNAL(readyRead()), this, SLOT(on_readyRead()));
        connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(on_downloadProgress(qint64, qint64)));
    }
    
    void MainWindow::on_btnDefaultPath_clicked()
    {
        QString curPath = QDir::currentPath();
        QDir dir(curPath);
        QString sub("temp");
        dir.mkdir(sub);
        ui->lineEditSavePath->setText(dir.path() + "/" + sub + "/");
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    在这里插入图片描述

    五、打包程序

    将指定程序打包,将依赖库打包进目录
    
    • 1
    D:\Qt\Qt5.13.0\5.13.0\mingw73_64\bin\windeployqt.exe E:/XXX/xxx.exe
    
    • 1

    在这里插入图片描述

  • 相关阅读:
    新生儿黄疸:原因、科普和注意事项
    UE4 UltrDynamicSky与场景物体进行交互
    解决“您的Chrome 浏览器由组织或机构管理”问题
    【数据结构】图的广度优先遍历
    五、Docker客户端和守护进程
    大话云原生数据库中的存算分离
    Python爬虫和数据分析,石油原油加工产品产量数据处理分析
    WebGL之使用着色器将颜色应用于 WebGL
    python自动化面试常见排序算法解析
    数据可视化系列教程之组件构成
  • 原文地址:https://blog.csdn.net/liutit/article/details/136358015