简述

对于一个C/S结构的程序,客户端有些时候需要实时得知与服务器的连接状态。而对于客户端与服务器断开连接的因素很多,现在就目前遇到的情况进行一下总结。

分为下面六种不同情况

  1. 客户端网线断开
  2. 客户端网络断开
  3. 客户端通过HTTP代理连接服务器,代理机器断开代理
  4. 客户端通过HTTP代理连接服务器,代理机器的网络断开
  5. 客户端通过HTTP代理连接服务器,代理机器的网线断开
  6. 服务器断开

同时对于以上六种情况又分为连接服务器之前和连接上服务器之后,下面就分别对不同的情况进行分析。

开始连接服务器之前

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的结果怎么样. 
同时在C++ 实现 ping 功能&& 域名(URL)解析实际 IP地址 这篇博客中用C++实现了 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()。 
当然这个只能检查你是否有网络链接,而不能检测你是否连接到互联网。


对于需要自动重连的客户端可以通过以上方法,在判断出与服务器断开后可以重新连接,或者通过超时定时器进行重连,方法很多,在于尝试。

http://blog.csdn.net/goforwardtostep/article/details/52300335

QTcpSocket 对连接服务器中断的不同情况进行判定(六种情况,其中一种使用IsNetworkAlive API方法)的更多相关文章

  1. Qt QTcpSocket 对连接服务器中断的不同情况进行判定

    简述 对于一个C/S结构的程序,客户端有些时候需要实时得知与服务器的连接状态.而对于客户端与服务器断开连接的因素很多,现在就目前遇到的情况进行一下总结. 分为下面六种不同情况 客户端网线断开 客户端网 ...

  2. QTcpSocket 对连接服务器中断的不同情况进行判定

    http://blog.csdn.net/goforwardtostep/article/details/52300335

  3. 使用paramiko如何连接服务器?

    本文和大家分享的是python开发中使用paramiko连接服务器的方法和步骤,希望通过本文的,对大家学习和使用paramiko有所帮助. ssh连接步骤 1.ssh server建立server p ...

  4. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(二) 之 ChatServer搭建,连接服务器,以及注意事项。

    上篇:ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据活起来(数据获取) 上一篇我们已经完成了初步界面的搭建工作,本篇将介绍IM的核心内容 ...

  5. 通过MSSQL连接服务器连接至Oracle数据库

    前言 有很多时候,我们需要MSSQL与Oracle进行跨库查询或数据交互.本篇随笔将阐述如何通过MSSQL的连接服务器连接至Oracle数据库,并且读取数据的示例. 具体步骤 首先需要到Oracle的 ...

  6. (转)OpenVPN使用HTTP代理连接服务器

    原文地址:http://www.365mini.com/page/18.htm 在一些公司或者其他受限的网络环境中,使用的是HTTP代理服务器上网.在这种情况下,使用OpenVPN客户端可能无法连接服 ...

  7. 无法远程连接服务器上的mysql

    使用mysql管理工具连接服务器删过得mysql,显示连接被拒绝,但是在服务器上是可以登录mysql的. 无法远程连接通常以下几种情况: 首先,关闭mysql.        service mysq ...

  8. pycharm安装,svn使用,远程开发调试,接口测试,连接服务器

    磨刀不误砍柴工,配置完美的编辑器,在开发时,能帮助我们节约大量的时间成本,从而是我们的精力放在业务逻辑实现上面! 接下来将介绍 使用pyhcarm如何使用svn,远程开发调试,接口测试,已经连接远程服 ...

  9. 远程连接服务器jupyter notebook、浏览器以及深度学习可视化方法

    h1 { counter-reset: h2counter; } h2 { counter-reset: h3counter; } h3 { counter-reset: h4counter; } h ...

随机推荐

  1. Docker + .NET Core(二)

    原文:Docker + .NET Core(二) 前言: 环境:centos7.5 64 位 正文: 首先我们在宿主机上安装 .NET Core SDK sudo rpm --import https ...

  2. Swift 中的Closures(闭包)详解

    Swift 中的Closures(闭包)详解 在Swift没有发布之前,所有人使用OC语言编写Cocoa上的程序,而其中经常被人们讨论的其中之一 -- Block 一直备受大家的喜爱.在Swift中, ...

  3. Hexo里如何添加广告

    前期先用Hexo做个人网站,模板可以用https://github.com/828768/maupassant-hexo,关于如何加入广告,可以看一下https://sobaigu.com/hexo- ...

  4. Android学习--Assets资源文件读取及AssetManager介绍

    APK安装过程        复制APK安装包到data/app目录下,解压并扫描安装包,把dex文件(Dalvik字节码)保存到dalvik-cache目录,并data/data目录下创建对应的应用 ...

  5. LoadFromStr的使用中出现错误“未结束的字符串常量”

    最近遇到个奇怪的问题,就是关于js参数中待换行符时,出现了错误“为结束的字符串常量”. 解决方法是:不直接将该数据以参数形式传递,而是先将其赋值在一个隐藏的文本内,需要调用的函数里只需读取该文本里的内 ...

  6. Android检测网络是否可用并获取网络类型

    在类中使用getSystemService的时候需要这样进行使用:1. public class JajaMenu extends Activity { public static JajaMenu ...

  7. Dx bad class file magic (cafebabe) or version (0033.0000) ant打包遇到问题2

    在进行ant进行打包时会发现下面的提示话语言 后来在网上搜索答案,问题得以解决,下面是传送门 门:http://blog.k-res.net/archives/1501.html 里面提到问题的原因是 ...

  8. Matlab Tricks(十四) —— 句柄(handle)(图形对象属性的读取与修改)

    0. 句柄的获得 H = subplot(1,2,1); saveas(H, [pathname,filename], 'jpg'); 1. h = plot(-) a = 0:10:360; x = ...

  9. 贝叶斯推理(Bayes Reasoning)、独立与因式分解

    P(X,Y)=P(X)P(Y),X⊥Y P(X,Y,Z)∝ϕ1(X,Z)ϕ2(Y,Z),(X⊥Y∣∣Z) 1. Reasoning patterns causal reasoning 由原因到结果的一 ...

  10. 零元学Expression Design 4 - Chapter 6 教你如何在5分钟内做出文字立体感效果

    原文:零元学Expression Design 4 - Chapter 6 教你如何在5分钟内做出文字立体感效果 又来一篇五分钟做设计啦~ 本篇将教大家如何运用Design内建工具Blend Path ...