本文主要介绍qt在网络编程方面的应用方法
1. QNetworkAccessManager(核心管理器)
核心功能:
- 发送 HTTP/HTTPS/FTP 等请求(GET/POST/PUT/DELETE 等);
- 管理网络配置(代理、Cookie、SSL 证书、超时);
- 复用网络连接(避免频繁创建连接)。
常用 API:
| 方法 |
作用 |
QNetworkReply* get(QNetworkRequest) |
发送 GET 请求(获取资源); |
QNetworkReply* post(QNetworkRequest, QByteArray) |
发送 POST 请求(提交数据,如表单、JSON); |
QNetworkReply* put(...) |
发送 PUT 请求(更新资源); |
void setProxy(QNetworkProxy) |
设置网络代理(如 HTTP 代理、SOCKS5); |
QNetworkCookieJar* cookieJar() |
获取 / 设置 Cookie 容器(管理会话 Cookie); |
关键注意:
- 一个程序建议只创建一个
QNetworkAccessManager 实例(多实例会浪费连接资源);
- 所有请求都是异步的,永远不要在主线程阻塞等待(除非用
QEventLoop 临时测试)。
2. QNetworkRequest(请求配置)
核心功能:
- 封装请求的 URL、请求头、超时、缓存策略、SSL 配置等。
常用 API:
| 方法 |
作用 |
setUrl(QUrl) |
设置请求的目标 URL(必选); |
setHeader(QNetworkRequest::KnownHeaders, QVariant) |
设置标准请求头(如 User-Agent、Content-Type); |
setRawHeader(QByteArray, QByteArray) |
设置自定义请求头(如 Token: xxx); |
setTransferTimeout(int msec) |
设置请求超时时间(毫秒); |
setSslConfiguration(QSslConfiguration) |
设置 HTTPS 证书配置(忽略证书错误、自定义证书); |
示例(POST JSON 配置):
1 2 3 4 5
| QNetworkRequest request(QUrl("https://api.example.com/post"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
request.setRawHeader("Authorization", "Bearer xxxxxx");
|
3. QNetworkReply(响应处理)
核心功能:
- 代表一个请求的响应,通过信号槽通知状态变化,提供响应数据 / 错误信息。
核心信号(异步处理关键):
| 信号 |
作用 |
finished() |
请求完成(成功 / 失败都会触发); |
errorOccurred(QNetworkReply::NetworkError) |
请求出错(如网络断开、404、500); |
readyRead() |
有响应数据可读取(分批接收大数据时用,如下载文件); |
downloadProgress(qint64 bytesReceived, qint64 bytesTotal) |
下载进度(文件下载时显示进度条); |
常用 API:
| 方法 |
作用 |
readAll() |
读取所有响应数据(小数据用,如接口返回的 JSON); |
read(qint64 maxSize) |
读取指定长度数据(大数据分批读取); |
error() |
获取错误码(NoError 表示无错误); |
errorString() |
获取错误描述(如 “Connection refused”); |
attribute(QNetworkRequest::Attribute) |
获取响应属性(如 HTTP 状态码、重定向 URL); |
header(QNetworkRequest::KnownHeaders) |
获取响应头(如 Content-Length、Content-Type); |
实战:异步 POST 请求(JSON 提交)
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
| #include <QMainWindow> #include <QNetworkAccessManager> #include <QNetworkRequest> #include <QNetworkReply> #include <QJsonDocument> #include <QJsonObject> #include <QDebug>
class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) { qnam = new QNetworkAccessManager(this);
QNetworkRequest request(QUrl("https://httpbin.org/post")); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setTransferTimeout(5000);
QJsonObject json; json["name"] = "Qt"; json["version"] = "6.6"; QByteArray postData = QJsonDocument(json).toJson(QJsonDocument::Compact);
QNetworkReply *reply = qnam->post(request, postData);
connect(reply, &QNetworkReply::finished, this, [=]() { if (reply->error() == QNetworkReply::NoError) { QByteArray data = reply->readAll(); QJsonDocument doc = QJsonDocument::fromJson(data); qDebug() << "POST 响应 JSON:" << doc.toJson(); int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); qDebug() << "HTTP 状态码:" << statusCode; } else { qDebug() << "POST 错误:" << reply->errorString(); } reply->deleteLater(); });
connect(reply, &QNetworkReply::errorOccurred, this, [=](QNetworkReply::NetworkError code) { qDebug() << "请求错误码:" << code << ",描述:" << reply->errorString(); }); }
private: QNetworkAccessManager *qnam; };
|
关键注意事项
- 资源释放:
QNetworkReply 必须调用 deleteLater() 释放(不能直接 delete,否则可能导致崩溃);
- 异步特性:所有请求都是异步的,不能在主线程阻塞等待(如
sleep),必须用信号槽处理结果;
- HTTPS 证书:默认情况下,Qt 会验证 HTTPS 证书,若证书无效(如自签名),请求会失败;可通过
QSslConfiguration 忽略证书错误(仅测试用,生产环境需配置合法证书):cpp运行
1 2 3
| QSslConfiguration config = QSslConfiguration::defaultConfiguration(); config.setPeerVerifyMode(QSslSocket::VerifyNone); request.setSslConfiguration(config);
|
- 大数据下载:若下载大文件(如图片、视频),不要用
readAll(),应在 readyRead() 信号中分批读取数据并写入文件:
1 2 3 4 5 6 7
| connect(reply, &QNetworkReply::readyRead, this, [=]() { QFile file("download.bin"); if (file.open(QIODevice::Append)) { file.write(reply->readAll()); file.close(); } });
|
- QNAM 生命周期:
QNetworkAccessManager 应作为全局对象(如类成员),避免频繁创建 / 销毁(否则会丢失 Cookie、断开持久连接)。
总结
| 类 |
一句话核心用法 |
QNetworkAccessManager |
全局单例,调用 get()/post() 发送请求,返回 QNetworkReply; |
QNetworkRequest |
配置 URL、请求头、超时等参数,作为 get()/post() 的入参; |
QNetworkReply |
监听 finished()/errorOccurred() 信号,读取响应数据 / 错误信息,最后 deleteLater(); |
Qt 网络模块的核心是 “异步非阻塞”,所有请求结果都通过信号槽处理,这是和传统同步网络请求的最大区别,也是 Qt 网络编程的核心原则。