十四、Qt主機信息與網絡編程

一、主機信息

1、主機信息接口

  • QHostInfo:獲取主機名稱和IP地址
  • QNetWorkInterface:獲取主機的所有網絡接口,包括子網掩碼和廣播地址等

(1)使用

項目添加模塊
QT       += network

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_OBJECTprivate: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
#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("");}
}

在這里插入圖片描述

二、TCP通信

TCP是一種被大多數Internet網絡協議(HTTP、FTP等)用于數據傳輸的低級網絡協議,是可靠的、面向流、面向連接的傳輸協議。

1、相關類

(1)繼承關系

QIODeviceQAbstractSocketQTcpSocketQSctpSocketQSslSocket // 加密QUdpSocket			

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_OBJECTprivate: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
#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(); //獲取socketconnect(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);
}

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_OBJECTprivate: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
#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();
}

在這里插入圖片描述

三、UDP通信

UDP用戶數據報協議,是輕量的、不可靠的、面向數據報、無連接的協議。

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();
}

在這里插入圖片描述

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();
}

在這里插入圖片描述

四、HTTP通信

1、相關類

QNetworkRequest,通過一個URL地址發起網絡請求,也保存網絡請求信息。
QNetworkAccessManager,用于協調網絡操作,在QNetworkRequest發起一個網絡請求后,負責發送網絡請求,創建網絡響應。
QNwtworkReply,網絡請求的響應。

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 + "/");
}

在這里插入圖片描述

五、打包程序

將指定程序打包,將依賴庫打包進目錄
D:\Qt\Qt5.13.0\5.13.0\mingw73_64\bin\windeployqt.exe E:/XXX/xxx.exe

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/714364.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/714364.shtml
英文地址,請注明出處:http://en.pswp.cn/news/714364.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【01】openEuler 源碼安裝 PostgreSQL

openEuler 源碼安裝 PostgreSQL 部署環境說明Shell 前端軟件包管理器基礎概念YUM 簡介DNF 簡介 源碼安裝 PostgreSQL環境變量&#xff08;env&#xff09;設置臨時環境變量設置永久環境變量設置 初始化數據庫&#xff08;initdb&#xff09; 數據庫基本操作數據庫基本配置&…

WiFi協議的調制技術介紹

調制技術是WiFi協議的核心部分&#xff0c;它負責將數據轉換成可以在無線信道中傳輸的信號。WiFi協議采用正交頻分復用&#xff08;OFDM&#xff09;調制技術&#xff0c;該技術通過將數據分成多個子載波進行傳輸&#xff0c;提高了信道利用率和抗干擾能力。 OFDM調制的工作原…

推特API(Twitter API)V2 用戶關注

前面章節已經介紹使用code換取Token的整個流程了&#xff0c;這里不再重復闡述了&#xff0c;下面我們獲取到用戶token以后如何幫用戶自動關注別人。需要參數關注者的用戶ID&#xff08;token授權用戶&#xff09;以及關注的目標用戶ID。用戶ID如何獲取可以看上一章節獲取用戶信…

c++結構體內存對齊

結構體內存對齊 試試運行下面的例子 #include <stdio.h> #include <stdlib.h>using namespace std;struct A{char c;int i; };struct B{char c; int i; double d; };struct C{char c;int i;double d;char c1; };int main(){printf("sizeof(A): %d\n"…

SparkStreaming在實時處理的兩個場景示例

簡介 Spark Streaming是Apache Spark生態系統中的一個組件&#xff0c;用于實時流式數據處理。它提供了類似于Spark的API&#xff0c;使開發者可以使用相似的編程模型來處理實時數據流。 Spark Streaming的工作原理是將連續的數據流劃分成小的批次&#xff0c;并將每個批次作…

適配器模式 詳解 設計模式

適配器模式 適配器模式是一種結構型設計模式&#xff0c;其主要作用是解決兩個不兼容接口之間的兼容性問題。適配器模式通過引入一個適配器來將一個類的接口轉換成客戶端所期望的另一個接口&#xff0c;從而讓原本由于接口不匹配而無法協同工作的類能夠協同工作。 結構 適配…

想要調用淘寶開放平臺API,沒有申請應用怎么辦?

用淘寶自定義API接口可以訪問淘寶開放平臺API。 custom-自定義API操作 taobao.custom 公共參數 注冊賬號獲取API請求地址 名稱類型必須描述keyString是調用key&#xff08;必須以GET方式拼接在URL中&#xff09;secretString是調用密鑰api_nameString是API接口名稱&#xf…

Docker與虛擬機比較

在對比Docker和虛擬機前&#xff0c;先簡單了解下虛擬化&#xff0c;明確Docker和虛擬機分別對應的虛擬化級別&#xff0c;然后對Docker和虛擬機進行比較。需要注意的是&#xff0c;Docker和虛擬機并沒有什么可比性&#xff0c;而是Docker使用的容器技術和虛擬機使用的虛擬化技…

【K8S類型系統】一文梳理 K8S 各類型概念之間的關系(GVK/GVR/Object/Schema/RestMapper)

參考 k8s 官方文檔 https://kubernetes.io/zh-cn/docs/reference/https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/ 重點 Kubernetes源碼學習-kubernetes基礎數據結構 - 知乎 重點 Kubernetes類型系統 | 李乾坤的博客 重點 k8s源碼學習-三大核心數…

前端學習第二天-html提升

達標要求 了解列表的分類 熟練掌握列表的用法 熟練掌握表格的結構構成 合并單元格 表單的組成 熟練掌握表單控件分類的使用 1.列表 1.1 無序列表 <ul>&#xff1a;定義無序列表&#xff0c;并且只能包含<li>子元素。 <li>&#xff1a;定義列表項&a…

LZO索引文件失效說明

在hive中創建lzo文件和索引時&#xff0c;進行查詢時會出現問題.hive的默認輸入格式是開啟小文件合并的&#xff0c;會把索引也合并進來。所以要關閉hive小文件合并功能&#xff01;

Matlab:元胞自動機

元胞自動機是一種基于離散空間的動態系統&#xff0c;由許多簡單單元按照某些規則進行相互作用和演化而形成的復雜結構。元胞自動機可以用于模擬物理、生物、社會等領域的現象&#xff0c;以及進行優化、圖像處理、噪聲生成等方面的應用。 例1&#xff1a;生命游戲 nextState…

maven項目報錯Cannot resolve plugin org.apache.maven.plugins:maven-war-plugin:2.2

如果IDEA整合maven沒有問題&#xff0c;還是報這個錯誤&#xff0c;很大可能是由于在下載過程中存在網絡問題&#xff0c;導致文件下載一半而停止&#xff0c;但是已經在倉庫中存在這個文件夾&#xff0c;解決方法是刪除文件夾重新下載即可。 刪除本地倉庫下的\org\apache\mav…

(算法)位運算

常見的位運算符&#xff1a; 給定一個數n判斷他的二進制第x位是0還是1 把第x位修改為1 因為是只是修改n的某個位置&#xff0c;所以不應該移動改變n 既然修改為1&#xff0c;那么就要想到 | 運算符 把第x位修改為0 因為修改為0,所以要用&運算符 位圖思想 判定字符串…

C++17之std::invoke: 使用和原理探究(全)

目錄 1.概述 2.輔助類 3.原理分析 4.總結 1.概述 在之前的 C 版本中&#xff0c;要調用不同類型的可調用對象&#xff0c;需要使用不同的語法&#xff0c;例如使用函數調用運算符 () 來調用函數或函數指針&#xff0c;使用成員訪問運算符 -> 或 . 來調用成員函數。這樣的…

二維碼門樓牌管理系統技術服務的深度解析

文章目錄 前言一、標準地址名稱的定義與重要性二、二維碼門樓牌管理系統的核心技術三、標準地址名稱在二維碼門樓牌管理中的應用四、二維碼門樓牌管理系統的優勢與挑戰五、展望未來 前言 在數字化浪潮中&#xff0c;二維碼門樓牌管理系統以其高效、便捷的特性&#xff0c;正逐…

【一】【算法分析與設計】基礎測試

排列式 題目描述 7254是一個不尋常的數&#xff0c;因為它可以表示為7254 39 x 186&#xff0c;這個式子中1~9每個數字正好出現一次 輸出所有這樣的不同的式子&#xff08;乘數交換被認為是相同的式子&#xff09; 結果小的先輸出&#xff1b;結果相同的&#xff0c;較小的乘…

js 實戰小案例

實戰 時間 js 格式化時間 <script type"text/javascript">function formatDate(date) { let year date.getFullYear(); let month String(date.getMonth() 1).padStart(2, 0); // getMonth() 返回的月份是從0開始的&#xff0c;所以要加1&#xff0c;并…

【go從入門到精通】go包,內置類型和初始化順序

大家好&#xff0c;這是我給大家準備的新的一期專欄&#xff0c;專門講golang&#xff0c;從入門到精通各種框架和中間件&#xff0c;工具類庫&#xff0c;希望對go有興趣的同學可以訂閱此專欄。 go基礎 。 Go文件名&#xff1a; 所有的go源碼都是以 ".go" 結尾&…

Mamba 環境安裝:causal-conv1d和mamba-ssm報錯解決辦法

問題描述&#xff1a; 在執行命令 pip install causal_conv1d 和 mamba_ssm 出錯&#xff1a; 解決方案&#xff1a; 1、使用網友配置好的Docker環境&#xff0c;參考&#xff1a;解決causal_conv1d和mamba_ssm無法安裝 -&#xff1e; 直接使用Mamba基礎環境docker鏡像 DockH…