Qt 网络编程如何采用Http进行通信
在 Qt 框架中进行 HTTP 通信时,最核心的三个类是:
QNetworkAccessManager
: 网络请求的管理者;
QNetworkRequest
: 用于封装请求的细节;
QNetworkReply
: 用于封装服务器返回的响应。
一、QNetworkRequest —— 网络请求的描述者
1.1 类定义与作用
QNetworkRequest
是用于封装一次 HTTP 请求的所有元信息的类,包括:
- 请求 URL;
- 请求头部信息;
- 缓存策略;
- 超时属性等。
1.2 构造函数
QNetworkRequest();
QNetworkRequest(const QUrl &url);
通常我们直接传入目标地址:
QNetworkRequest request(QUrl("https://api.example.com/data"));
1.3 设置请求头
通过 setRawHeader()
或 setHeader()
设置常用 HTTP 头:
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
request.setRawHeader("User-Agent", "MyQtApp/1.0");
常用枚举值有:
Header 枚举 | 说明 |
---|---|
ContentTypeHeader | 设置 MIME 类型(如 JSON) |
UserAgentHeader | 客户端信息 |
ContentLengthHeader | 设置正文长度 |
LocationHeader | 重定向位置 |
1.4 其他属性设置
可以用 setAttribute()
设置附加属性,如:
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
二、QNetworkReply —— 网络响应的容器
2.1 类定义与作用
QNetworkReply
是 QIODevice
的子类,用于接收并读取来自服务器的响应内容。
它包含:
- 响应状态码;
- 响应头部;
- 响应体数据;
- 网络错误信息等。
2.2 读取响应内容
最常见的用法是等待请求完成后读取所有数据:
QByteArray response = reply->readAll();
配合事件循环等待异步完成:
QEventLoop loop;
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();
2.3 错误处理
if (reply->error() != QNetworkReply::NoError) {qWarning() << "Request failed:" << reply->errorString();
}
QNetworkReply::NetworkError
提供了丰富的错误枚举,例如:
ConnectionRefusedError
TimeoutError
HostNotFoundError
ContentNotFoundError
2.4 获取状态码和头部
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString();
三、结合示例讲解完整流程
以下是一个完整的 GET 请求流程代码,并在每步配合类讲解。
#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QEventLoop>
#include <QDebug>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 1. 创建网络管理器QNetworkAccessManager manager;// 2. 构建请求QUrl url("https://jsonplaceholder.typicode.com/posts/1");QNetworkRequest request(url);// 设置请求头request.setRawHeader("User-Agent", "QtNetworkClient/1.0");request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");// 3. 发送 GET 请求QNetworkReply *reply = manager.get(request);// 4. 等待请求完成(阻塞)QEventLoop loop;QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);loop.exec();// 5. 处理响应if (reply->error() == QNetworkReply::NoError) {QByteArray data = reply->readAll();int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();qDebug() << "Status:" << statusCode;qDebug() << "Response:" << data;} else {qWarning() << "Network error:" << reply->errorString();}// 6. 清理资源reply->deleteLater();return 0;
}
四、进阶用法拓展
4.1 POST 请求(发送表单或 JSON)
QByteArray json = R"({"title": "foo", "body": "bar"})";
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkReply *reply = manager.post(request, json);
4.2 异步请求处理
推荐用信号槽非阻塞处理:
QObject::connect(reply, &QNetworkReply::finished, []() {qDebug() << "Request finished!";
});
五、总结
类名 | 作用 |
---|---|
QNetworkRequest | 描述 HTTP 请求,包括 URL、header、属性等 |
QNetworkReply | 封装服务器响应,包括数据、状态码、错误等 |
用法核心 | 发出请求(GET/POST)后读取 reply 内容 |