QT 通过QNetworkAccessManager进行http请求的超时与同步异步处理

QT 通过QNetworkAccessManager进行http请求的超时与同步异步处理
  • QNetworkAccessManager是QT的网络包,可以设置超时,见下面代码。
QReplyTimeout *pTimeout = new QReplyTimeout(reply, 2000);
   //  超时进一步处理
    connect(pTimeout, &QReplyTimeout::timeout, [=]() {
        qDebug() << "Timeout";
		this->loginMutex.unlock();
		return;
    });

  • 但是默认是异步的,每次点击执行发起http请求时会新开一个线程执行,主函数立即就结束了,读数据以槽函数的形式在另一个线程读取。这样有一定优势,不占用主线程资源,但是有个问题是如果确实需要同步的情形,或者访问在返回前只需要一次,这样防止重复提交。网上实现方法主要是通过阻塞的形式,如下:
	QEventLoop eventLoop;
	connect(pManger2, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
	eventLoop.exec();       //block until finish

这种方式在一定程度上可以实现同步,但是在测试过程中重复频繁发起请求时,由于多线程同时对reply进行操作,会出现段错误,很难通过较验来判断。
而且,这种方法阻塞了主线程,会对程序有影响。

  • 于是想到了另一种方法,那就是加锁,通过Qmutx的tryLock,和unlock的来进行控制,完美的实现了访问控制,同时只访问一次(而且是非阻塞)。当然unlock要放在两个地方,一个是超时的槽函数里,另一个是接收槽函数内。需要进一步测试会不会有其他异常。

void MainWindow::on_readyRead(){

	qDebug() << reply->error() << endl;
    QByteArray resp = reply->readAll();
    ui->textEdit->append(resp);
    qDebug()<<"on_readyRead"<<endl;
	this->loginMutex.unlock();
}


void MainWindow::on_pushButton_clicked()
{
	if (!this->loginMutex.tryLock()) {
		qDebug() << "already locked return" << endl;
		return;
	}

    pManger = new QNetworkAccessManager(this);
    //pManger = new QNetworkAccessManager();

    reply= pManger->get(QNetworkRequest(QUrl("http://www.csdn.net")));
    QReplyTimeout *pTimeout = new QReplyTimeout(reply, 2000);
   //  qDebug()<<reply->readAll()<<endl;
   //  超时进一步处理
    connect(pTimeout, &QReplyTimeout::timeout, [=]() {
        qDebug() << "Timeout";
		this->loginMutex.unlock();
		return;
    });
    connect(reply,SIGNAL(finished()),this,SLOT(on_readyRead()));
    qDebug()<<""<<endl;
    qDebug()<<"after ret 异步"<<endl;
}

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值