QT 如何实现HTTP的同步访问

众所周知,Qt的网络操作类是异步(非阻塞的),但是有些场景却需要同步(阻塞)的网络访问,同时还需要加入超时设置(超过设定的时间,不再等待网络返回)。

1、示例代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include void httpGET(const QString& strUrl, QString& response, int& statusCode)
{assert(!strUrl.isEmpty());const QUrl url = QUrl::fromUserInput(strUrl);assert(url.isValid());//QNetworkAccessManager* manager = new QNetworkAccessManager;QNetworkRequest request(url);request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");QScopedPointer<QNetworkReply> reply(manager->get(request));//wait.QEventLoop eventLoop;QTimer::singleShot(5000, &eventLoop, [&]() { if (eventLoop.isRunning()) { eventLoop.quit(); } });QObject::connect(reply.data(), &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);eventLoop.exec(QEventLoop::ExcludeUserInputEvents);//status codestatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();//responseif (reply->error() == QNetworkReply::NoError){QByteArray data = reply->readAll();response = QString::fromLocal8Bit(data);}else {response = reply->errorString().toUtf8();}reply->deleteLater();
}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);int statusCode = 0;QString response;QString strUrl = "http://wthrcdn.etouch.cn/weather_mini?citykey=101010100";httpGET(strUrl, response, statusCode);qDebug() << "statusCode=" << statusCode << "\nresponse=" << response;return a.exec();
}

2、知识点

2.1、EventLoop的事件类型

ConstantDescription
QEventLoop::AllEventsAll events. Note that DeferredDelete events are processed specially. See QObject::deleteLater() for more details.
QEventLoop::ExcludeUserInputEventsDo not process user input events, such as ButtonPress and KeyPress. Note that the events are not discarded; they will be delivered the next time processEvents() is called without the ExcludeUserInputEvents flag.
QEventLoop::ExcludeSocketNotifiersDo not process socket notifier events. Note that the events are not discarded; they will be delivered the next time processEvents() is called without the ExcludeSocketNotifiers flag.
QEventLoop::WaitForMoreEventsWait for events if no pending events are available.

关于对 QEventLoop::ExcludeUserInputEvents 的理解:

用户输入的事件并不会被丢弃,而是等到QEventLoop 退出后再响应。像类似按钮按下和键盘按下,依然响应多次,只是响应的时间推迟。

2.2、超时的处理
引起网络连接超时的原因很多,比如:

  • 网络断开,经常显示无法连接
  • 网络阻塞,导致你不能在程序默认等待时间内得到回复数据包
  • 网络不稳定,网络无法完整传送服务器信息
  • 设备不稳定,如网线松动、接口没插好等等 网络注册时系统繁忙,无法回应
  • 网速过慢,使用 BT 多线程下载,在线收看视频等大量占用带宽的软件
  • 其他等等等原因

我们可以通过定时器,来实现超时控制。在达到超时限制时,自动退出EventLoop的事件循环,以此来避免网络的无尽等待。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部