一、主机信息
1、主机信息接口
- QHostInfo:获取主机名称和IP地址
- QNetWorkInterface:获取主机的所有网络接口,包括子网掩码和广播地址等
(1)使用
项目添加模块
QT += network
2、实现程序
(1)创建项目,基于QDialog
(2)实现功能
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;
};
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)继承关系
QIODevice
QAbstractSocket
QTcpSocket
QSctpSocket
QSslSocket // 加密
QUdpSocket
2、实现服务端程序
(1)创建项目
(2)添加图标资源
(3)实现服务器功能
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;
};
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);
}
3、实现客户端程序
(1)创建项目
(2)添加图标资源
(3)实现功能
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;
};
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)实现功能
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)实现功能
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)实现功能
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
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