天天看點

Qt之處理QNetworkAccessManager網絡連接配接逾時簡述逾時原因Qt 中的網絡連接配接逾時如何處理逾時封裝類

在網絡操作中,經常會由于各種原因引起網絡連接配接逾時,究竟何為網絡連接配接逾時?

網絡連接配接逾時:在程式預設的等待時間内沒有得到伺服器的響應

<a href="#%e7%ae%80%e8%bf%b0">簡述</a>

<a href="#%e8%b6%85%e6%97%b6%e5%8e%9f%e5%9b%a0">逾時原因</a>

<a href="#qt-%e4%b8%ad%e7%9a%84%e7%bd%91%e7%bb%9c%e8%bf%9e%e6%8e%a5%e8%b6%85%e6%97%b6">qt 中的網絡連接配接逾時</a>

<a href="#%e5%a6%82%e4%bd%95%e5%a4%84%e7%90%86%e8%b6%85%e6%97%b6">如何處理逾時</a>

<a href="#%e5%b0%81%e8%a3%85%e7%b1%bb">封裝類</a>

引起網絡連接配接逾時的原因很多,下面,列舉一些常見的原因:

網絡斷開,不過經常顯示無法連接配接

網絡阻塞,導緻你不能在程式預設等待時間内得到回複資料包

網絡不穩定,網絡無法完整傳送伺服器資訊

系統問題,系統資源過低,無法為程式提供足夠的資源處理伺服器資訊

裝置不穩定,如網線松動、接口沒插好等等

網絡注冊時系統繁忙,無法回應

網速過慢,如 使用 bt 多線程下載下傳,線上收看視訊等大量占用帶寬的軟體 ,若使用共享帶寬還要防範他人惡意占用帶寬

計算機感染了惡意軟體,計算機病毒,計算機木馬等

在 qt 中,關于 qnetworkaccessmanager、qnetworkrequest 和 qnetworkreply 的文檔中,找到了有關逾時相關的錯誤 qnetworkreply::networkerror。

常量 qnetworkreply::timeouterror:

the connection to the remote server timed out

瞬間欣喜若狂,既然有逾時錯誤,必然有設定逾時的接口吧!遺憾,遺憾,遺憾。。。重要的事情說 3 遍,翻遍了官方文檔,能和逾時扯上關系的就這麼一個簡單的常量說明(當然還有 qnetworkreply::proxytimeouterror)。

這種情況下,我們隻能自己去處理逾時了。

解決思路:

使用 qtimer 啟動一個單次定時器,并設定逾時時間。

在事件循環退出之後,判斷定時器的狀态,如果是激活狀态,證明請求已經完成;否則,說明逾時。

首先,定義一個 qtimer,設定逾時時間為 30000 毫秒(30 秒)并設定為單次觸發。然後,使用 qnetworkrequest 實作一個簡單的網絡請求,通過 qnetworkaccessmanager::get() 開始擷取 qt 官網的 html 頁面内容。因為請求過程是異步的,是以通過使用 qeventloop 啟動一個事件循環讓其同步處理,并将 qtimer 的 timeout() 信号以及 qnetworkreply 的 finished() 信号連接配接至其 quit() 槽函數,保證在定時器過期之後或者網絡響應完成後事件循環得到退出,不至于一直處于阻塞狀态。

如上所述,事件循環退出的兩種情況:

qtimer 30 秒到期,逾時

網絡連接配接響應完成

是以,當 qtimer::isactive() 激活的情況下,證明響應完成,還尚未逾時。這時需要先調用 qtimer::stop() 來停止定時器,再對響做進一步處理。否則,進行逾時處理 - qnetworkreply::abort() 立即中止操作并關閉網絡連接配接。

既然以後會經常用到,那麼還是提供一個封裝類 qreplytimeout 專門處理逾時。

由于 qnetworkreply 和 qreplytimeout 是父子關系,是以 qreplytimeout 将被自動銷毀。

使用起來非常簡單:

如果對 google 的擷取未在 1000 毫秒(1 秒)内完成,則會中止,并發出 timeout() 信号,供進一步處理(例如:提示使用者請求逾時)。

繼續閱讀