我是靠谱客的博主 自觉哈密瓜,最近开发中收集的这篇文章主要介绍QT 如何实现HTTP的同步访问,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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

1、示例代码

#include <QtCore/QCoreApplication>
#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrlQuery>
#include <QUrl>
#include <QEventLoop>
#include <QTextCodec>
#include <QTimer>


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 code
	statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
	//response
	if (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的事件循环,以此来避免网络的无尽等待。

最后

以上就是自觉哈密瓜为你收集整理的QT 如何实现HTTP的同步访问的全部内容,希望文章能够帮你解决QT 如何实现HTTP的同步访问所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(69)

评论列表共有 0 条评论

立即
投稿
返回
顶部