当前位置:   article > 正文

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

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

一、主机信息

1、主机信息接口

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

(1)使用

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

2、实现程序

在这里插入图片描述

(1)创建项目,基于QDialog

在这里插入图片描述

(2)实现功能

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>

#include <QHostInfo>
#include <QNetworkInterface>

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 <QMainWindow>
#include <QTcpSocket>
#include <QTcpServer>
#include <QLabel>

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 <QHostInfo>

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 <QMainWindow>
#include <QMainWindow>
#include <QTcpSocket>
#include <QLabel>


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 <QHostInfo>

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 <QHostInfo>

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 <QDir>
#include <QMessageBox>

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

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

#include <QDesktopServices>
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

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/184712
推荐阅读
相关标签
  

闽ICP备14008679号