首页 > 代码库 > 为QNetworkAccessManager添加超时提醒(自己记录一段时间里的下载字节数,用定时器去定期检测,从而判断是否超时)

为QNetworkAccessManager添加超时提醒(自己记录一段时间里的下载字节数,用定时器去定期检测,从而判断是否超时)

在做更新,在测试异常的时候,在下载过程中,发现如果直接系统禁用了网络,会报错误,可以捕获。但是如果是第三方软件限制程序联网,问题来了。

程序会一直在那里等待,没有异常,也不发送QNetworkAccessManager::finsh和QNetworkReply::error和QNetworkReply::finsh信号。

所以动念头为下载加个超时,但是QNetworkAccessManager,QNetworkReply和QNetworkRequest都没有相关的设置函数。其实仔细想一下,也没有办法直接提供超时,因为下载的文件有大有小,网络有快有慢,什么才算超时呢。只有自己想办法添加了。因为这个异常必须想办法发现并处理它,那么问题就必须要解决了。

先说下我的解决思路,利用QNetworkReply::downloadProgress 信号来实现,自己记录一段时间里的下载字节数,用定时器去定期检测,如果一段时间了,一点多余的下载都没有,那么我就认为网络超时异常了。

下面就上代码,自己简单用代码描述下:

声明:

01class NetWorkDownload : public QObject
02{
03    Q_OBJECT
04public:
05    explicit NetWorkDownload(QObject *parent = 0);
06signals:
07    void timeOut();
08    //····你的其他需要传递出去的信号
09public slots:
10    void startDownload(const QString & url);
11     
12protected slots:
13    void handleReply(QNetworkReply * rep);//处理下载完成的数据
14    void handSize(qint64 size, qint64 all);
15    void handleTimeOut();
16private:
17    QNetworkAccessManager manger;
18    int fileDownSize,//已经下载的字节数
19        lastDownSize;//定时器上次下载的字节数
20    QTimer tm;//定时器
21};

实现:

01NetWorkDownload::NetWorkDownload(QObject *parent) :
02    QObject(parent)
03{
04    //这个connect你也可以用QNetworkReply来链接,QNetworkReply::finsh,QNetworkReply::readyReady这些信号。
05    connect(&manger,&QNetworkAccessManager::finished,this,&NetWorkDownload::handleReply);
06    connect(&tm,&QTimer::timeout,this,&NetWorkDownload::timeOut);
07}
08 
09void NetWorkDownload::startDownload(const QString & url)
10{
11    QNetworkRequest req;
12    req.setUrl(QUrl(url));
13    auto rep = manger.get(req);
14    connect(rep,&QNetworkReply::downloadProgress,this,&NetWorkDownload::handSize);
15    //启动超时定时,30s。
16    if (tm.isActive())
17        tm.stop();
18    tm.start(30000);
19}
20 
21void NetWorkDownload::handSize(qint64 size,qint64 /* all*/)
22{
23    fileDownSize = size;
24}
25 
26void NetWorkDownload::handleReply(QNetworkReply *rep)
27{
28    /*
29    下载完成的您的处理代码。
30    */
31    fileDownSize = 0;
32    lastDownSize = 0;
33    if (tm.isActive())//如果还在定时,就停止
34        tm.stop();
35}
36 
37void NetWorkDownload::timeOut()
38{
39    if (lastDownSize != fileDownSize)//如果过了30s,一点字节也没有下载过来,认为超时了。
40        lastDownSize = fileDownSize;
41    else
42        emit timeOut();
43}

 

http://www.dushibaiyu.com/2014/10/qnetworkaccessmanager-timeout.html

http://stackoverflow.com/questions/13207493/qnetworkreply-and-qnetworkaccessmanager-timeout-in-http-request

为QNetworkAccessManager添加超时提醒(自己记录一段时间里的下载字节数,用定时器去定期检测,从而判断是否超时)