在做更新,在測試異常的時候,在下載過程中,發現如果直接系統禁用了網絡,會報錯誤,可以捕獲。但是如果是第三方軟件限制程序聯網,問題來了。
程序會一直在那里等待,沒有異常,也不發送QNetworkAccessManager::finsh和QNetworkReply::error和QNetworkReply::finsh信號。
所以動念頭為下載加個超時,但是QNetworkAccessManager,QNetworkReply和QNetworkRequest都沒有相關的設置函數。其實仔細想一下,也沒有辦法直接提供超時,因為下載的文件有大有小,網絡有快有慢,什么才算超時呢。只有自己想辦法添加了。因為這個異常必須想辦法發現並處理它,那么問題就必須要解決了。
先說下我的解決思路,利用QNetworkReply::downloadProgress 信號來實現,自己記錄一段時間里的下載字節數,用定時器去定期檢測,如果一段時間了,一點多余的下載都沒有,那么我就認為網絡超時異常了。
下面就上代碼,自己簡單用代碼描述下:
聲明:
01 |
class NetWorkDownload : public QObject |
02 |
{ |
03 |
Q_OBJECT |
04 |
public : |
05 |
explicit NetWorkDownload(QObject *parent = 0); |
06 |
signals: |
07 |
void timeOut(); |
08 |
//····你的其他需要傳遞出去的信號 |
09 |
public slots: |
10 |
void startDownload( const QString & url); |
11 |
|
12 |
protected slots: |
13 |
void handleReply(QNetworkReply * rep); //處理下載完成的數據 |
14 |
void handSize(qint64 size, qint64 all); |
15 |
void handleTimeOut(); |
16 |
private : |
17 |
QNetworkAccessManager manger; |
18 |
int fileDownSize, //已經下載的字節數 |
19 |
lastDownSize; //定時器上次下載的字節數 |
20 |
QTimer tm ; //定時器 |
21 |
}; |
實現:
01 |
NetWorkDownload::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 |
09 |
void 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 |
21 |
void NetWorkDownload::handSize(qint64 size,qint64 /* all*/ ) |
22 |
{ |
23 |
fileDownSize = size; |
24 |
} |
25 |
26 |
void NetWorkDownload::handleReply(QNetworkReply *rep) |
27 |
{ |
28 |
/* |
29 |
下載完成的您的處理代碼。 |
30 |
*/ |
31 |
fileDownSize = 0; |
32 |
lastDownSize = 0; |
33 |
if ( tm .isActive()) //如果還在定時,就停止 |
34 |
tm .stop(); |
35 |
} |
36 |
37 |
void 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