网络编程
Qt 提供了强大的网络编程支持,包括 HTTP 请求、TCP/UDP 通信等功能。
QNetworkAccessManager(HTTP 请求)
用于发送 HTTP 请求和处理响应。
GET 请求
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
class HttpClient : public QObject
{
Q_OBJECT
public:
HttpClient(QObject *parent = nullptr) : QObject(parent)
{
manager = new QNetworkAccessManager(this);
}
void get(const QString &url)
{
QNetworkRequest request(QUrl(url));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkReply *reply = manager->get(request);
connect(reply, &QNetworkReply::finished, this, [=]() {
if (reply->error() == QNetworkReply::NoError) {
QByteArray data = reply->readAll();
QString text = QString::fromUtf8(data);
qDebug() << "响应:" << text;
} else {
qDebug() << "错误:" << reply->errorString();
}
reply->deleteLater();
});
}
private:
QNetworkAccessManager *manager;
};
POST 请求
void post(const QString &url, const QJsonObject &json)
{
QNetworkRequest request(QUrl(url));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QJsonDocument doc(json);
QByteArray data = doc.toJson();
QNetworkReply *reply = manager->post(request, data);
connect(reply, &QNetworkReply::finished, this, [=]() {
if (reply->error() == QNetworkReply::NoError) {
QByteArray response = reply->readAll();
QJsonDocument doc = QJsonDocument::fromJson(response);
QJsonObject obj = doc.object();
// 处理响应
}
reply->deleteLater();
});
}
// 使用示例
QJsonObject json;
json["username"] = "admin";
json["password"] = "123456";
post("https://api.example.com/login", json);
文件下载
void downloadFile(const QString &url, const QString &savePath)
{
QNetworkRequest request(QUrl(url));
QNetworkReply *reply = manager->get(request);
QFile *file = new QFile(savePath);
if (!file->open(QIODevice::WriteOnly)) {
delete file;
return;
}
connect(reply, &QNetworkReply::readyRead, this, [=]() {
file->write(reply->readAll());
});
connect(reply, &QNetworkReply::finished, this, [=]() {
file->close();
delete file;
reply->deleteLater();
if (reply->error() == QNetworkReply::NoError) {
qDebug() << "下载完成";
}
});
// 下载进度
connect(reply, &QNetworkReply::downloadProgress, this,
[=](qint64 bytesReceived, qint64 bytesTotal) {
if (bytesTotal > 0) {
int percent = static_cast<int>((bytesReceived * 100) / bytesTotal);
qDebug() << "下载进度:" << percent << "%";
}
});
}
QTcpSocket(TCP 客户端)
#include <QTcpSocket>
class TcpClient : public QObject
{
Q_OBJECT
public:
TcpClient(QObject *parent = nullptr) : QObject(parent)
{
socket = new QTcpSocket(this);
connect(socket, &QTcpSocket::connected, this, [=]() {
qDebug() << "已连接到服务器";
});
connect(socket, &QTcpSocket::disconnected, this, [=]() {
qDebug() << "与服务器断开连接";
});
connect(socket, &QTcpSocket::readyRead, this, [=]() {
QByteArray data = socket->readAll();
qDebug() << "收到数据:" << data;
});
connect(socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error),
this, [=](QAbstractSocket::SocketError error) {
qDebug() << "错误:" << socket->errorString();
});
}
void connectToHost(const QString &host, quint16 port)
{
socket->connectToHost(host, port);
}
void send(const QByteArray &data)
{
if (socket->state() == QAbstractSocket::ConnectedState) {
socket->write(data);
}
}
void disconnect()
{
socket->disconnectFromHost();
}
private:
QTcpSocket *socket;
};
QTcpServer(TCP 服务器)
#include <QTcpServer>
#include <QTcpSocket>
class TcpServer : public QObject
{
Q_OBJECT
public:
TcpServer(QObject *parent = nullptr) : QObject(parent)
{
server = new QTcpServer(this);
connect(server, &QTcpServer::newConnection, this, [=]() {
QTcpSocket *client = server->nextPendingConnection();
clients.append(client);
qDebug() << "新客户端连接:" << client->peerAddress().toString();
connect(client, &QTcpSocket::readyRead, this, [=]() {
QByteArray data = client->readAll();
qDebug() << "收到:" << data;
// 广播给所有客户端
broadcast(data, client);
});
connect(client, &QTcpSocket::disconnected, this, [=]() {
qDebug() << "客户端断开";
clients.removeAll(client);
client->deleteLater();
});
});
}
bool start(quint16 port)
{
return server->listen(QHostAddress::Any, port);
}
void broadcast(const QByteArray &data, QTcpSocket *except = nullptr)
{
for (QTcpSocket *client : clients) {
if (client != except && client->state() == QAbstractSocket::ConnectedState) {
client->write(data);
}
}
}
private:
QTcpServer *server;
QList<QTcpSocket*> clients;
};
QUdpSocket(UDP 通信)
#include <QUdpSocket>
class UdpClient : public QObject
{
Q_OBJECT
public:
UdpClient(QObject *parent = nullptr) : QObject(parent)
{
socket = new QUdpSocket(this);
socket->bind(QHostAddress::Any, 12345);
connect(socket, &QUdpSocket::readyRead, this, [=]() {
while (socket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(socket->pendingDatagramSize());
QHostAddress sender;
quint16 port;
socket->readDatagram(datagram.data(), datagram.size(), &sender, &port);
qDebug() << "收到来自" << sender.toString() << ":" << port << "的数据:" << datagram;
}
});
}
void send(const QByteArray &data, const QString &host, quint16 port)
{
socket->writeDatagram(data, QHostAddress(host), port);
}
private:
QUdpSocket *socket;
};
下一步
Qt 网络编程基础已介绍完毕。建议继续深入学习 Qt 的线程编程,以实现高效的网络通信应用。