Qt网络编程:QNetworkReply

一、描述

QNetworkReply 类封装了使用 QNetworkAccessManager 发布的请求相关的回复信息。

QNetworkReply 是 QIODevice的子类,这意味着一旦从对象中读取数据,它就不再由设备保留。因此,如果需要,应用程序有责任保留这些数据。

注意:不要删除连接到errorOccurred() 或finished() 信号的槽中的对象。应该使用使用 deleteLater()。


二、类型成员

1、enum QNetworkReply::NetworkError:指示在处理请求期间发现的所有可能的错误情况。

  • NoError:没有错误。(当 HTTP 协议返回重定向时,不会报告错误。可以使用 QNetworkRequest::RedirectionTargetAttribute 属性检查是否存在重定向)
  • ConnectionRefusedError:远程服务器拒绝连接。
  • RemoteHostClosedError:远程服务器在接收和处理整个回复之前过早关闭了连接。
  • HostNotFoundError:未找到远程主机名(无效主机名)。
  • TimeoutError:与远程服务器的连接超时。
  • OperationCanceledError:操作在完成之前通过调用 abort() 或 close() 被取消。
  • SslHandshakeFailedError:SSL/TLS 握手失败,无法建立加密通道。 sslErrors() 信号应该已经发出。
  • TemporaryNetworkFailureError:由于与网络断开连接,连接中断,但系统已开始漫游到另一个接入点。 应重新提交请求,并在重新建立连接后立即进行处理。
  • NetworkSessionFailedError:由于与网络断开连接或无法启动网络,连接中断。
  • BackgroundRequestNotAllowedError:由于平台政策,当前不允许后台请求。
  • TooManyRedirectsError:在跟随重定向时,达到了最大限制。 该限制默认设置为 50 或由 QNetworkRequest::setMaxRedirectsAllowed() 设置。 
  • InsecureRedirectError:在跟踪重定向时,网络访问 API 检测到从加密协议 (https) 到未加密协议 (http) 的重定向。
  • ProxyConnectionRefusedError:与代理服务器的连接被拒绝(代理服务器不接受请求)。
  • ProxyConnectionClosedError:代理服务器在接收和处理整个回复之前过早地关闭了连接。
  • ProxyNotFoundError:未找到代理主机名(无效的代理主机名)。
  • ProxyTimeoutError:与代理的连接超时或代理没有及时回复发送的请求。
  • ProxyAuthenticationRequiredError:代理需要身份验证才能满足请求,但不接受任何提供的凭据(如果有)。
  • ContentAccessDenied:对远程内容的访问被拒绝(类似于 HTTP 错误 403)。
  • ContentOperationNotPermittedError:不允许对远程内容请求的操作。
  • ContentNotFoundError:在服务器上找不到远程内容(类似于 HTTP 错误 404)。
  • AuthenticationRequiredError:远程服务器需要身份验证才能提供内容,但不接受提供的凭据(如果有)。
  • ContentReSendError:需要再次发送请求,但由于无法再次读取上传数据而失败。
  • ContentConflictError:由于与资源的当前状态冲突,无法完成请求。
  • ContentGoneError:请求的资源在服务器上不再可用。
  • InternalServerError:服务器遇到意外情况,无法完成请求。
  • OperationNotImplementedError:服务器不支持满足请求所需的功能。
  • ServiceUnavailableError:服务器此时无法处理请求。
  • ProtocolUnknownError:网络访问 API 无法接受请求,因为协议未知。
  • ProtocolInvalidOperationError:请求的操作对该协议无效。
  • UnknownNetworkError:检测到与网络相关的未知错误。
  • UnknownProxyError:检测到与代理相关的未知错误。
  • UnknownContentError:检测到与远程内容相关的未知错误。
  • ProtocolFailure:检测到协议故障(解析错误、无效或意外响应等)。
  • UnknownServerError:检测到与服务器响应相关的未知错误。

三、成员函数

1、void abort()

立即中止操作并关闭所有仍打开的网络连接。仍在进行中的上传会中止,finished() 信号也将被发射。

2、[signal] void downloadProgress(qint64 bytesReceived, qint64 bytesTotal)

发出此信号以指示此网络请求的下载部分的进度(如果有)。如果没有与此请求关联的下载,则此信号将发出一次,bytesReceived 和 bytesTotal 的值都为0。

bytesReceived 指示接收的字节数,bytesTotal 指示预期下载的总字节数。如果要下载的字节数未知,bytesTotal 将为 -1。当 bytesReceived 等于 bytesTotal 时,下载完成。

请注意,bytesReceived 和 bytesTotal 的值可能与 size()、通过 read() 或 readAll() 获取的总字节数或 header(ContentLengthHeader) 的值不同。原因是可能存在协议开销或数据在下载过程中可能被压缩。

3、[signal] void encrypted()

当 SSL/TLS 会话成功完成初始握手时,会发出此信号。此时还没有传输用户数据。此信号可用于对证书链执行额外检查,例如在网站证书更改时通知用户。如果回复与预期标准不匹配,则应通过连接到此信号的插槽调用 abort() 来中止。 可以使用 sslConfiguration() 方法检查正在使用的 SSL 配置。

4、[signal] void errorOccurred(QNetworkReply::NetworkError code)

出现错误时发出此信号。代码参数包含检测到的错误代码。调用 errorString() 以获取错误条件的文本表示。

5、[signal] void finished()

当回复完成处理时发出此信号。发出此信号后,将不再更新回复的数据。

除非调用 close() 或 abort() ,否则仍将打开回复以供读取,因此可以通过调用 read() 或 readAll() 来检索数据。特别是,如果 readyRead() 的结果没有调用 read(),则调用 readAll() 将检索 QByteArray 中的全部内容。

此信号与 QNetworkAccessManager::finished() 一起发出,该信号的回复参数是此对象。

6、void ignoreSslErrors()

如果调用此函数,将忽略与网络连接相关的 SSL 错误,包括证书验证错误。

警告:应确保始终让用户检查 sslErrors() 信号报告的错误,并且只有在用户确认继续正常后才调用此方法。如果出现意外错误,则应中止回复。在不检查实际错误的情况下调用此方法很可能会给应用程序带来安全风险。应小心使用此函数!

可以从连接到 sslErrors() 信号的插槽调用此函数,该信号指示发现了哪些错误。

注意:如果 QNetworkAccessManager 启用了 HTTP Strict Transport Security,则此功能无效。

7、[signal] void metaDataChanged()

每当元数据发生更改时,都会发出此信号。元数据是任何不属于内容(数据)本身的信息,包括网络标头。

8、[signal] void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator)

如果 SSL/TLS 握手协商 PSK 密码套件,则会发出此信号,因为需要 PSK 身份验证。

使用 PSK 时,客户端必须向服务器发送一个有效的身份和一个有效的预共享密钥,以便 SSL 握手继续进行。 应用程序可以在连接到这个信号的槽中提供这个信息,通过根据他们的需要填充传递的验证器对象。

注意:忽略此信号,或未能提供所需的凭据,将导致握手失败,从而中止连接。

9、[signal] void redirected(const QUrl &url)

如果在请求中设置了 FollowRedirectsAttribute 并且服务器以 3xx 状态(特别是 301、302、303、305、307 或 308 状态代码)在location header中带有有效的 url(如:header("Location: http://www.baidu.com/")),则发出此信号,指示 HTTP 重定向。url 参数包含服务器在location header中返回的新重定向 url。

10、[signal] void redirectAllowed()

当处理 redirected() 信号的客户端代码验证了新 URL 时,会发出此信号以允许重定向继续进行。 适用于重定向策略设置为 UserVerifiedRedirectPolicy 的网络请求。

11、[signal] void sslErrors(const QList &errors)

如果 SSL/TLS 会话在设置期间遇到错误,包括证书验证错误,则会发出此信号。errors 参数包含错误列表。

如果错误不是致命的并且连接应该继续,应该从连接到此信号的槽函数调用 ignoreSslErrors() 。如果未调用,则在交换任何数据(包括 URL)之前,SSL 会话将被结束。

此信号可用于向用户显示错误消息,指示安全性可能受到威胁并显示 SSL 设置。如果用户在分析远程证书后决定继续连接,则槽函数应调用 ignoreSslErrors()。

12、[signal] void uploadProgress(qint64 bytesSent, qint64 bytesTotal)

发出此信号以指示此网络请求的上传部分的进度(如果有)。 如果没有与此请求关联的上传,则不会发出此信号。

bytesSent 表示上传的字节数,bytesTotal 表示要上传的总字节数。 如果无法确定要上传的字节数,则 bytesTotal 将为 -1。当 bytesSent 等于 bytesTotal 时,上传完成。

13、void close()

关闭此设备。未读的数据会被丢弃,但网络资源直到读完才被释放。如果有任何上传正在进行,它将一直持续到完成。当所有操作结束并且网络资源被释放时,finished() 信号被发出。

14、bool hasRawHeader(const QByteArray &headerName)

如果名称 headerName 的原始标头是由远程服务器发送的,则返回 true。

15、void ignoreSslErrors(const QList<QSslError> &errors)

列表中给出的 SSL 错误将被忽略。

注意:由于大多数 SSL 错误都与证书相关联,因此对于其中的大多数错误,必须设置与 SSL 错误相关的预期证书。例如,如果您想向使用自签名证书的服务器发出请求,请考虑以下代码段:

 QList<QSslCertificate> cert = QSslCertificate::fromPath(QLatin1String("server-certificate.pem"));
 QSslError error(QSslError::SelfSignedCertificate, cert.at(0));
 QList<QSslError> expectedSslErrors;
 expectedSslErrors.append(error);

 QNetworkReply * reply = manager.get(QNetworkRequest(QUrl("https://server.tld/index.html")));
 reply->ignoreSslErrors(expectedSslErrors);

注意:如果 QNetworkAccessManager 启用了 HTTP Strict Transport Security,则此功能无效。

16、void ignoreSslErrorsImplementation(const QList<QSslError> &errors)

虚函数,作用是供用户自定义内容以覆盖 ignoreSslErrors() 。参数列表是用户希望忽略的错误。

 ignoreSslErrors()实际上是调用的ignoreSslErrorsImplementation():

17、bool isFinished() 

是否回复完成或中止。

18、bool isRunning()

isFinished() 相反。

19、QNetworkAccessManager *manager()

返回用于创建此 QNetworkReply 对象的 QNetworkAccessManager。

20、QList<QByteArray> rawHeaderList()

返回远程服务器发送的标头字段列表,按发送顺序排列。

21、QNetworkRequest request()

返回为此回复发布的请求。特别要注意,请求的 URL 可能与回复的 URL 不同。

22、QByteArray rawHeader(const QByteArray &headerName) 

返回远程服务器发送的标头 headerName 的原始内容。 如果没有这样的标头,则返回一个空字节数组,它可能与空标头无法区分。 使用 hasRawHeader() 来验证服务器是否发送了这样的头字段。

23、QVariant header(QNetworkRequest::KnownHeaders header)

如果该标头是由远程服务器发送的,则返回已知标头标头的值。如果未发送标头,则返回无效的 QVariant。

24、QSslConfiguration sslConfiguration()

如果使用了 SSL,则返回与此回复关联的 SSL 配置和状态。

25、QUrl url()

返回下载或上传的内容的 URL。 请注意,该 URL 可能与原始请求的 URL 不同。 如果在请求中设置了 QNetworkRequest::FollowRedirectsAttribute,则此函数返回正在访问的当前 url,即 redirected() 信号中发出的 url。

26、qint64 readBufferSize()

返回读取缓冲区的大小,以字节为单位。从网络下载的数据保存到读写缓冲区,然后再使用 QIODevice::read() 读取。此值为 0 表示读写缓冲区的大小不受限制。
一旦该缓冲区已满(即,bytesAvailable() 返回大小或更多),QNetworkReply 将尝试停止从网络读取,从而导致下载也受到限制。 如果缓冲区的大小没有限制,QNetworkReply 将尝试尽快从网络下载。
QAbstractSocket::setReadBufferSize() 不同,QNetworkReply 不能保证读取缓冲区大小的精度。也就是说, QIODevice::bytesAvailable() 可以返回大于 readBufferSize() 的值。

  • 12
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt提供了QNetworkAccessManager类用于实现HTTP网络编程。通过QNetworkAccessManager,你可以发送HTTP请求并接收响应。 以下是一个简单的示例代码,演示了如何使用QNetworkAccessManager发送GET请求并接收响应: ```cpp #include <QtNetwork> int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QNetworkAccessManager manager; QUrl url("http://www.example.com"); // 要发送请求的URL QNetworkRequest request(url); QNetworkReply* reply = manager.get(request); // 发送GET请求 QObject::connect(reply, &QNetworkReply::finished, [&]() { if (reply->error() == QNetworkReply::NoError) { QByteArray data = reply->readAll(); // 读取响应数据 qDebug() << data; } else { qDebug() << "Error: " << reply->errorString(); } app.quit(); }); return app.exec(); } ``` 在这个示例中,我们创建了一个QNetworkAccessManager对象,并通过QUrl设置要发送请求的URL。然后,我们使用QNetworkRequest将URL传递给QNetworkAccessManager的get()函数,以发送GET请求。通过连接QNetworkReply的finished信号,我们可以在请求完成后获取响应数据。 当请求完成时,我们检查QNetworkReplyerror()函数以确定是否发生错误。如果没有错误发生,我们可以使用readAll()函数读取响应数据,并输出到控制台。否则,我们输出错误信息。 需要注意的是,由于网络请求是异步进行的,我们使用QCoreApplication的exec()函数来进入事件循环,以等待请求完成。在请求完成后,我们通过调用QCoreApplication的quit()函数来退出事件循环。 这只是一个简单的示例,你可以根据具体需求设置请求头、发送POST请求等。Qt的文档中有更详细的说明和示例代码,你可以参考官方文档来深入学习Qt网络编程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值