1.综述
QNetworkReply类包含用QNetworkAccessManager发送的请求的数据和报头
QNetworkReply类包含与QNetworkAccessManager发布的请求相关的数据和元数据。像QNetworkRequest一样,它包含一个URL和报头(以解析的和原始的形式),一些关于应答状态的信息和应答本身的内容。
QNetworkReply是一个顺序访问的QIODevice,这意味着一旦从对象中读取数据,它就不再被设备保存。因此,如果需要,应用程序有责任保存这些数据。每当从网络接收并处理更多数据时,就会发出readyRead()信号。
当接收到数据时,downloadProgress()信号也会发出,但如果对内容进行了任何转换(例如,解压和删除协议开销),则其中包含的字节数可能不代表实际接收的字节数。
即使QNetworkReply是一个连接到应答内容的QIODevice,它也会发出uploadProgress()信号,该信号指示具有此类内容的操作的上传进度。
注意:不要删除连接到error()或finished()信号的槽中的对象。应该使用deleteLater()。
参见QNetworkRequest和QNetworkAccessManager。
2.重要的信号
void QIODevice::readyRead()
该信号继承自QIODevice类,在设备当前读取通道中每次有新的数据可用时发出。 它只会在有新数据可用时再次发出,例如当新的网络数据负载到达您的网络套接字时,或者当一个新的数据块被附加到您的设备时。
readyRead()不是递归发出的; 如果你重新进入事件循环或在连接到readyRead()信号的槽中调用waitForReadyRead(),该信号将不会被重新发出(尽管waitForReadyRead()仍然可能返回true)。
注意,在实现QIODevice类的派生类时:当有新数据到达时,你应该总是发出readyRead()(不要仅仅因为缓冲区中还有数据需要读取才发出readyRead())。 不要在其他条件下发出readyRead()。
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
发出这个信号是为了指示这个网络请求的下载部分的进度(如果有的话)。如果没有与此请求相关的下载,这个信号将被发送一次,并以0作为bytesReceived和bytestal的值。
bytesReceived参数表示接收的字节数,而bytestal表示预期下载的总字节数。如果不知道要下载的字节数,bytesTotal将为-1。
当bytesReceived等于bytestal时,下载结束。到那时,bytesTotal将不会是-1。
注意bytesReceived和bytestal的值可能不同于size(),通过read()或readAll()获得的总字节数,或头的值(ContentLengthHeader)。这样做的原因是可能会有协议开销,或者在下载过程中数据可能被压缩。
想要获取更多信息,课查阅uploadProgress()和bytesAvailable()。
void encrypted()
这个信号在SSL/TLS会话成功完成初始握手时发出。此时,还没有传输用户数据。该信号可用于对证书链执行额外的检查,例如在网站的证书更改时通知用户。如果应答不符合预期的条件,那么它应该通过一个连接到这个信号的槽调用QNetworkReply::abort()来中止。使用中的SSL配置可以使用QNetworkReply::sslConfiguration()方法检查。
在内部,QNetworkAccessManager可以打开到服务器的多个连接,以便允许它并行处理请求。这些连接可以被重用,这意味着不会发出encrypted()信号。这意味着,在QNetworkAccessManager的生命周期中,您只保证在第一次连接到站点时收到此信号。
请参见QSslSocket::encrypted()和QNetworkAccessManager::encrypted()。
void error(QNetworkReply::NetworkError code)
当应答检测到处理中的错误时,就会发出这个信号。finished()信号可能随后出现,指示连接结束。
code参数包含检测到的错误的代码。调用errorString()以获得错误条件的文本表示。
注意:不要删除连接到该信号的槽中的对象。应该使用deleteLater()。
注意:本信号在这个类中是重载的。要使用函数指针语法连接到这个函数,你必须在静态转换中指定信号类型,如下例所示:
connect(networkReply, static_cast<void(QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
[=](QNetworkReply::NetworkError code){ /* ... */ });
void finished()
该信号在应答完成处理时发出。在发出此信号后,应答的数据或元数据将不再有更新。
除非调用了close()或abort(),否则应答仍将打开以供读取,因此可以通过调用read()或readAll()来检索数据。特别是,如果readyRead()没有调用read(),则调用readAll()将检索QByteArray中的全部内容。
这个信号是与QNetworkAccessManager::finished()一起发出的,在QNetworkAccessManager::finished()中,信号的reply参数就是这个对象。
注意:不要删除连接到该信号的槽中的对象。应该使用deleteLater()。
您还可以使用isFinished()来检查QNetworkReply是否已经完成,甚至在您收到finished()信号之前。
请参见setFinished(), QNetworkAccessManager::finished()和isFinished()。
void metaDataChanged()
每当此应答中的元数据发生更改时,就会发出此信号。元数据是不是内容(数据)本身的任何信息,包括网络头。在大多数情况下,元数据在接收到数据的第一个字节时就已经完全知道了。但是,在数据处理期间,可以接收头或其他元数据的更新。
参见header(), rawHeaderList(), rawHeader()和hasRawHeader()。
void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator)
如果SSL/TLS握手协商PSK密码套件,则会发出该信号,因此需要进行PSK身份验证。
当使用PSK时,客户端必须向服务器发送一个有效的身份和一个有效的预共享密钥,以便SSL握手继续。应用程序可以在连接到该信号的槽中提供此信息,方法是根据它们的需要填充所传递的验证器对象。
注意:忽略这个信号,或者不能提供所需的凭证,将导致握手失败,因此连接将被中止。
注意:authenticator对象由reply拥有,应用程序不能删除它。
void redirectAllowed()
当处理redirected()信号的客户端代码验证了新URL后,它会发出这个信号,以允许继续重定向。该协议适用于重定向策略为“QNetworkRequest::userverifiedredirectpolicy”的网络请求。
void redirected(const QUrl &url)
如果在请求中设置了QNetworkRequest::FollowRedirectsAttribute,并且服务器用3xx状态(特别是301、302、303、305、307或308状态码)响应,在位置报头中使用一个有效的url,指示HTTP重定向,则会发出这个信号。url参数包含服务器在位置报头中返回的新重定向url。
void sslErrors(const QList<QSslError> &errors)
如果SSL/TLS会话在设置过程中遇到错误,包括证书验证错误,则会发出此信号。errors参数包含错误列表。
为了表明错误不是致命的,并且连接应该继续,应该从连接到这个信号的槽调用ignoreSslErrors()函数。如果没有调用它,SSL会话将在交换任何数据(包括URL)之前被拆除。
此信号可用于向用户显示一条错误消息,表明安全性可能受到损害,并显示SSL设置(请参阅sslConfiguration()获取该设置)。如果用户决定在分析远程证书之后继续,那么插槽应该调用ignoreSslErrors()。
void uploadProgress(qint64 bytesSent, qint64 bytesTotal)
发出这个信号是为了指示这个网络请求的上传部分的进度(如果有的话)。如果没有与此请求关联的上传,则不会发出此信号。
bytesSent表示已上传的字节数,bytesTotal表示上传的总字节数。如果无法确定要上传的字节数,bytesTotal将为-1。
当bytesSent等于bytesTotal时,上传完成。到那时,bytesTotal将不会是-1。