qt TcpSocket 對連線伺服器中斷的不同情況進行判定
簡述
對於一個C/S結構的程式,客戶端有些時候需要實時得知與伺服器的連線狀態。而對於客戶端與伺服器斷開連線的因素很多,現在就目前遇到的情況進行一下總結。
分為下面六種不同情況
- 客戶端網線斷開
- 客戶端網路斷開
- 客戶端通過HTTP代理連線伺服器,代理機器斷開代理
- 客戶端通過HTTP代理連線伺服器,代理機器的網路斷開
- 客戶端通過HTTP代理連線伺服器,代理機器的網線斷開
- 伺服器斷開
同時對於以上六種情況又分為連線伺服器之前和連線上伺服器之後,下面就分別對不同的情況進行分析。
開始連線伺服器之前
1、 客戶端網線斷開
此時用socket呼叫connectToHost方法連線伺服器會立即觸發QTcpSocket的error訊號,我們可以繫結相應的槽去處理連線失敗的結果。
2、 客戶端網路斷開
3、 客戶端通過HTTP代理連線伺服器,代理機器斷開代理
4、 客戶端通過HTTP代理連線伺服器,代理機器的網路斷開
5.、客戶端通過HTTP代理連線伺服器,代理機器的網線斷開
6、 伺服器斷開
此時用socket呼叫connectToHost方法連線伺服器並不會立即觸發QTcpSocket的error訊號,而是經過40s+的連線等待超時發出error訊號,見下圖。
已經連線上伺服器
1、 客戶端網線斷開
此時socket不會傳送error訊號,也不會傳送disconnect訊號,查詢資料是因為網線斷開是屬於物理鏈路層,tcp無法察覺到,socket仍處於連線狀態。
2、 客戶端網路斷開
3、 客戶端通過HTTP代理連線伺服器,代理機器斷開代理
4、 客戶端通過HTTP代理連線伺服器,代理機器的網路斷開
5.、客戶端通過HTTP代理連線伺服器,代理機器的網線斷開第二和第三種情況下會立即觸發error訊號,而第四和第五種情況下會等待30s左右會傳送error訊號。
6、 伺服器斷開
此時socket會傳送disconnect訊號,可以繫結相應的槽去處理伺服器斷開的情況。
檢測與伺服器斷開的另外方法
對於有些程式(客戶端)需要立即知道與服務端連線狀態,而不是等待幾十秒之後才有訊號通知到或者根本就檢測不出與伺服器斷開,除了利用QTcpSocket提供的訊號(有幾種情況不會發出訊號或發出訊號延遲),這裡列出另外幾種處理方法。
1、傳送心跳包,即客戶端每隔一段時間傳送一條報文,報文不需附帶具體內容,只需要讓服務端知道這是一條心跳報文,並回發一條訊息,客戶端收到這條訊息後就得知與伺服器保持連線的狀態。
檢測本地網路,定義一個時鐘,每次timeout去檢測本地的網路,關於怎麼判斷本地網路是否通暢呢?
2、可以用windows提供的IsNetworkAlive方法,返回為false為網路異常。加上標頭檔案為#include “Sensapi.h”。同時需要包含Sensapi.lib。
(通過IsNetworkAlive方法判斷本地網路,在客戶端已經連線上伺服器,並且禁用網路時會立即傳送error訊號,在error訊號繫結的槽中去呼叫這個方法發現返回值為true,因為這種情況下禁用網路後會立即傳送error訊號,呼叫IsNetworkAlive方法時可能立即檢測不到網路異常。如果通過斷點的方式,在呼叫IsNetworkAlive時就會返回false)
DWORD dwFlag;
if (FALSE == IsNetworkAlive(&dwFlag))
{
qDebug() << "NetWorkError";
}
注意:
但是這種方法,在本地存在虛擬機器並且虛擬機器開啟時會失效,因為IsNetworkAlive會檢測本地所有的網路,在網線斷開後,可能檢測到虛擬機器網路正常,導致返回ture。
3、如果有自己的伺服器就ping伺服器(前提伺服器不會掛),否則就ping一個相對可靠的IP (比如百度),通過看他ping的結果怎麼樣.
QProcess *cmd = new QProcess;
cmd->start("ping www.baidu.com");
// 等待ping 的結果
while (cmd->waitForFinished())
{
QString result = QString::fromLocal8Bit(cmd->readAll());
qDebug() << result;
}
或
QHostInfo::lookupHost("www.baidu.com", this, SLOT(lookedUp(QHostInfo)));
void lookedUp(QHostInfo &host)
{
qDebug() << host.addresses().first().toString();
}
//得到IP 地址 就是在網際網路上 如果不能得到 就不行
4、QNetworkConfigurationManager::isOnline()。
當然這個只能檢查你是否有網路連結,而不能檢測你是否連線到網際網路。
對於需要自動重連的客戶端可以通過以上方法,在判斷出與伺服器斷開後可以重新連線,或者通過超時定時器進行重連,方法很多,在於嘗試。
相關文章
- Qt QTcpSocket 對連線伺服器中斷的不同情況進行判定QTTCP伺服器
- Qt TcpSocket的掉線解決方法QTTCP
- 如何對伺服器進行24小時不間斷監控?伺服器
- 如何對Wormhole進行連線Worm
- 伺服器的連線情況?伺服器
- 相關技術連線,不斷新增中...
- 保持ssh的連線不斷開
- java連線池解決連線中斷Java
- 操作選中cell 所有cell操作相同情況下
- cmd 工具 ssh 保持連線不斷開
- 對列進行連線操作會影響索引的使用索引
- abap submit 的使用方法 不同情況MIT
- SSH無需密碼登入伺服器且保持連線不斷開的方法密碼伺服器
- MQTT伺服器連線不上的問題MQQT伺服器
- 對於網線斷開後重新連上 tcp socket 連線保持 ESTABLISH 狀態不變的問題的解釋(轉)TCP
- 一次對連線過程進行跟蹤處理連線故障問題的案例
- 實現Xshell斷開連線情況下Linux命令繼續執行Linux
- Qt TCP通訊客戶端斷開連線有哪些方法QTTCP客戶端
- vmware中控制檯的連線已斷開…正在嘗試重新連線
- 使用 SOS 對 Linux 中執行的 .NET Core 進行問題診斷Linux
- 外連線轉換為內連線的情況
- Qt中通過ODBC連線MSSQL資料庫QTSQL資料庫
- Qt中連線到同一signal的多個slots的執行順序問題QT
- 使用secureCRT連線伺服器,防超時斷開Securecrt伺服器
- 無線網路卡狀態不對問題:已連線 顯示 未連線
- VScode遠端連線伺服器連線不上,各種神奇的報錯VSCode伺服器
- MyBatis中對於字串blank(null、empty)的判定方法MyBatis字串Null
- VMware Workstation 下進行 橋連線
- vscode連線遠端伺服器docker容器進行開發VSCode伺服器Docker
- Qt 中多執行緒對應的訊號槽QT執行緒
- navicat連線遠端伺服器docker的mysql容器時連不上報錯伺服器DockerMySql
- Revit二次開發-曲線三連:對curves進行排序排序
- ArduinoUNO連線藍芽模組與安卓連線進行測距UI藍芽模組安卓
- SecureCRT連線CentOS不間斷出現“Connection was reset.”SecurecrtCentOS
- 伺服器遠端桌面連線不上 伺服器批次管理伺服器
- Qt對基本控制元件進行美化 QStyle和QStyleSheetQT控制元件
- 如何透過連線資料庫的方式對線下應用進行線上擴充套件資料庫套件
- WebSocket斷線重連Web