简述

对于一个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?locationNum=4

Qt QTcpSocket 对连接服务器中断的不同情况进行判定的更多相关文章

  1. QTcpSocket 对连接服务器中断的不同情况进行判定(六种情况,其中一种使用IsNetworkAlive API方法)

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

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

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

  3. Qt实现客户端与服务器消息发送

    这里用Qt来简单设计实现一个场景,即: ①两端:服务器QtServer和客户端QtClient ②功能:服务端连接客户端,两者能够互相发送消息,传送文件,并且显示文件传送进度. 环境:VS20013+ ...

  4. Qt实现客户端与服务器消息发送与文件传输

    Qt实现客户端与服务器消息发送与文件传输需要使用到 QTcpSocket:提供套接字QTcpServer:提供基于TCP的服务端,官方文档的解释如下: This class makes it poss ...

  5. Qt通过ODBC连接SQL Server2008实践总结

    Qt连接数据库的方式很多,这里说明一种最常用也是最实用的方式,因为这种方式在Windows上开发程序使用起来非常方便,并且也是远程连接数据库所需要用到的方式. 前提工作: 在Win7下安装了SQL S ...

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

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

  7. Mac 使用 SSH 免密连接服务器

    1.生成 SSH 秘钥 ssh-keygen -t rsa  生成的密钥对 id_rsa 和 id_rsa.pub,默认存储在 ~/.ssh 目录,其中没有后缀的是私有,有后缀 .pub 的为公钥.生 ...

  8. telnet命令——连接服务器

    Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式.它为用户提供了在本地计算机上完成远程主机工作的能力.在终端使用者的电脑上使用telnet程序,用它连接 ...

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

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

随机推荐

  1. macbook中vagrant升级新版本

    macbook由于缺少卸载机制,有时候不知道该如何升级软件. vagant的升级到时简单,经测试,只需直接官网下载新软件,安装即可. 旧版本不用管,新的会直接替换.

  2. Unity GPU Instancing的使用尝试

    似乎是在Unity5.4中开始支持GPU Instacing,但如果要比较好的使用推荐用unity5.6版本,因为这几个版本一直在改. 这里测试也是使用unity5.6.2进行测试 在5.6的版本里, ...

  3. android 自己定义视频播放器之2/1

    非常久没更新博客,相信大家年后都比較忙. 今天给大家带来了一款视频播放器,首先确认的得有几点. 1.首先得有个播放视频的view. 2.加点额外功能进去左边上下滑动调节亮度,右边上下滑动调节声量: 3 ...

  4. 菜鸟学Java(九)——Servlet的基本配置

    学习JavaWeb的人没有不知道Servlet的吧,而要用Servlet就需要在web.xml中进行配置.相信有很多初学者跟我当初一样,对于一些配置参数不是很理解,今天就说说Servlet最基本的配置 ...

  5. 360wifi: 手机锁屏360wifi掉线的解决方法

    如遇到iphone锁屏断网的情况,按照以下操作步骤可以解决一部分用户的问题 (该问题并不是360WifFi问题,与苹果机制有关)如有安卓手机掉线,请确保手机连接其他Wifi并不会掉线,然后尝试粉色字体 ...

  6. Redis source code analysis

    http://zhangtielei.com/posts/blog-redis-dict.html http://zhangtielei.com/assets/photos_redis/redis_d ...

  7. OpenStack大规模部署详解

    https://blog.csdn.net/karamos/article/details/80130443 0.前言今年的2月22日,OpenStack发布了15个版本Ocata. 走过了7年的发展 ...

  8. linux系统卡解决方案

    1.查看内存使用率 free -g 运行结果: 2.查看磁盘使用率 df -h 运行结果: 3.查看磁盘IO iostat -x 1 运行结果: 60表示60秒钟刷新一次 4.查看CPU使用情况 to ...

  9. Lua函数[转]

    在大多数Lua语法分析中可以获得这些标准Lua函数. 无可争辩, 我们可以查阅Lua网站, 但是一些少了的函数被Blizzard进行了调整. 下面列出了所有Lua函数. WoW API中的Lua注意在 ...

  10. 【架构】MVC模式

    架构模式 如何设计一个程序的结构,这是一门专门的学问,叫做"架构模式"(architectural pattern),属于编程的方法论. MVC模式就是架构模式的一种,它不仅适用于 ...