Qt QTcpSocket 对连接服务器中断的不同情况进行判定
簡(jiǎn)述
對(duì)于一個(gè)C/S結(jié)構(gòu)的程序,客戶端有些時(shí)候需要實(shí)時(shí)得知與服務(wù)器的連接狀態(tài)。而對(duì)于客戶端與服務(wù)器斷開連接的因素很多,現(xiàn)在就目前遇到的情況進(jìn)行一下總結(jié)。
分為下面六種不同情況
同時(shí)對(duì)于以上六種情況又分為連接服務(wù)器之前和連接上服務(wù)器之后,下面就分別對(duì)不同的情況進(jìn)行分析。
開始連接服務(wù)器之前
1、 客戶端網(wǎng)線斷開?
此時(shí)用socket調(diào)用connectToHost方法連接服務(wù)器會(huì)立即觸發(fā)QTcpSocket的error信號(hào),我們可以綁定相應(yīng)的槽去處理連接失敗的結(jié)果。
2、 客戶端網(wǎng)絡(luò)斷開?
3、 客戶端通過HTTP代理連接服務(wù)器,代理機(jī)器斷開代理?
4、 客戶端通過HTTP代理連接服務(wù)器,代理機(jī)器的網(wǎng)絡(luò)斷開?
5.、客戶端通過HTTP代理連接服務(wù)器,代理機(jī)器的網(wǎng)線斷開?
6、?服務(wù)器斷開?
此時(shí)用socket調(diào)用connectToHost方法連接服務(wù)器并不會(huì)立即觸發(fā)QTcpSocket的error信號(hào),而是經(jīng)過40s+的連接等待超時(shí)發(fā)出error信號(hào),見下圖。
已經(jīng)連接上服務(wù)器
1、 客戶端網(wǎng)線斷開?
此時(shí)socket不會(huì)發(fā)送error信號(hào),也不會(huì)發(fā)送disconnect信號(hào),查詢資料是因?yàn)榫W(wǎng)線斷開是屬于物理鏈路層,tcp無法察覺到,socket仍處于連接狀態(tài)。
2、 客戶端網(wǎng)絡(luò)斷開?
3、 客戶端通過HTTP代理連接服務(wù)器,代理機(jī)器斷開代理?
4、 客戶端通過HTTP代理連接服務(wù)器,代理機(jī)器的網(wǎng)絡(luò)斷開?
5.、客戶端通過HTTP代理連接服務(wù)器,代理機(jī)器的網(wǎng)線斷開
第二和第三種情況下會(huì)立即觸發(fā)error信號(hào),而第四和第五種情況下會(huì)等待30s左右會(huì)發(fā)送error信號(hào)。
6、?服務(wù)器斷開?
此時(shí)socket會(huì)發(fā)送disconnect信號(hào),可以綁定相應(yīng)的槽去處理服務(wù)器斷開的情況。
檢測(cè)與服務(wù)器斷開的另外方法
對(duì)于有些程序(客戶端)需要立即知道與服務(wù)端連接狀態(tài),而不是等待幾十秒之后才有信號(hào)通知到或者根本就檢測(cè)不出與服務(wù)器斷開,除了利用QTcpSocket提供的信號(hào)(有幾種情況不會(huì)發(fā)出信號(hào)或發(fā)出信號(hào)延遲),這里列出另外幾種處理方法。
1、發(fā)送心跳包,即客戶端每隔一段時(shí)間發(fā)送一條報(bào)文,報(bào)文不需附帶具體內(nèi)容,只需要讓服務(wù)端知道這是一條心跳報(bào)文,并回發(fā)一條消息,客戶端收到這條消息后就得知與服務(wù)器保持連接的狀態(tài)。
檢測(cè)本地網(wǎng)絡(luò),定義一個(gè)時(shí)鐘,每次timeout去檢測(cè)本地的網(wǎng)絡(luò),關(guān)于怎么判斷本地網(wǎng)絡(luò)是否通暢呢?
2、可以用windows提供的IsNetworkAlive方法,返回為false為網(wǎng)絡(luò)異常。加上頭文件為#include “Sensapi.h”。同時(shí)需要包含Sensapi.lib。?
(通過IsNetworkAlive方法判斷本地網(wǎng)絡(luò),在客戶端已經(jīng)連接上服務(wù)器,并且禁用網(wǎng)絡(luò)時(shí)會(huì)立即發(fā)送error信號(hào),在error信號(hào)綁定的槽中去調(diào)用這個(gè)方法發(fā)現(xiàn)返回值為true,因?yàn)檫@種情況下禁用網(wǎng)絡(luò)后會(huì)立即發(fā)送error信號(hào),調(diào)用IsNetworkAlive方法時(shí)可能立即檢測(cè)不到網(wǎng)絡(luò)異常。如果通過斷點(diǎn)的方式,在調(diào)用IsNetworkAlive時(shí)就會(huì)返回false)
注意:
但是這種方法,在本地存在虛擬機(jī)并且虛擬機(jī)開啟時(shí)會(huì)失效,因?yàn)镮sNetworkAlive會(huì)檢測(cè)本地所有的網(wǎng)絡(luò),在網(wǎng)線斷開后,可能檢測(cè)到虛擬機(jī)網(wǎng)絡(luò)正常,導(dǎo)致返回ture。
3、如果有自己的服務(wù)器就ping服務(wù)器(前提服務(wù)器不會(huì)掛),否則就ping一個(gè)相對(duì)可靠的IP (比如百度),通過看他ping的結(jié)果怎么樣.?
同時(shí)在C++ 實(shí)現(xiàn) ping 功能&& 域名(URL)解析實(shí)際 IP地址?這篇博客中用C++實(shí)現(xiàn)了 ping的 功能,有興趣的小伙伴可以看一看,了解一下。
或
QHostInfo::lookupHost("www.baidu.com", this, SLOT(lookedUp(QHostInfo)));void lookedUp(QHostInfo &host) {qDebug() << host.addresses().first().toString(); } //得到IP 地址 就是在互聯(lián)網(wǎng)上 如果不能得到 就不行4、QNetworkConfigurationManager::isOnline()。?
當(dāng)然這個(gè)只能檢查你是否有網(wǎng)絡(luò)鏈接,而不能檢測(cè)你是否連接到互聯(lián)網(wǎng)。
對(duì)于需要自動(dòng)重連的客戶端可以通過以上方法,在判斷出與服務(wù)器斷開后可以重新連接,或者通過超時(shí)定時(shí)器進(jìn)行重連,方法很多,在于嘗試。
?
轉(zhuǎn)自:http://blog.csdn.net/GoForwardToStep/article/details/52300335?locationNum=4
轉(zhuǎn)載于:https://www.cnblogs.com/liushui-sky/p/6473539.html
總結(jié)
以上是生活随笔為你收集整理的Qt QTcpSocket 对连接服务器中断的不同情况进行判定的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 货店管理(delphi+sqlserve
- 下一篇: svn cleanup failed–p