• 对端正常close socket,或者进程退出(正常退出或崩溃),对端系统正常关闭

这种情况下,协议栈会走正常的关闭状态转移,使用epoll的话,一般要判断如下几个情况

    • 处理可读事件时,在循环read后,返回结果为0
    • 处理可写事件时,write返回-1,errno为EPIPE
    • EPOLLERR或EPOLLHUP或事件
  • 对端非正常断开,比如服务器断电,网线被拔掉

这种情况下,协议栈无法感知,SO_KEEPALIVE这个选项的超时事件太长并不实用,一般还是以应用层的heartbeat来及时发现。

下面来罗列一下判断远端已经断开的方法:

法一:

当recv()返回值小于等于0时,socket连接断开。但是还需要判断 errno是否等于 EINTR,如果errno == EINTR 则说明recv函数是由于程序接收到信号后返回的,socket连接还是正常的,不应close掉socket连接。

法二:

struct tcp_info info; 
  int len=sizeof(info); 
  getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);
  if((info.tcpi_state==TCP_ESTABLISHED))  则说明未断开  else 断开

法三:

若使用了select等系统函数,若远端断开,则select返回1,recv返回0则断开。其他注意事项同法一。

法四:

int keepAlive = 1; // 开启keepalive属性
int keepIdle = 60; // 如该连接在60秒内没有任何数据往来,则进行探测
int keepInterval = 5; // 探测时发包的时间间隔为5 秒
int keepCount = 3; // 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.

setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));

设置后,若断开,则在使用该socket读写时立即失败,并返回ETIMEDOUT错误

法五:

自己实现一个心跳检测,一定时间内未收到自定义的心跳包则标记为已断开。

参考:

1. 知乎:怎样实时判断socket链接状态?

2. 知乎:socket长连接是否会超时?连接中断,客户端或者服务器端是否一定能得到通知呢?

3. 如何判断SOCKET已经断开

4. TCP socket如何判断连接断开

5. 服务器中判断客户端socket断开连接的方法

6. tcp 服务端如何判断客户端断开连接

怎样实时判断socket连接状态?的更多相关文章

  1. java socket 判断Socket连接失效

    要判断socket连接链路是否可用时,不能通过socket.isClosed() 和 socket.isConnected() 方法判断,要通过心跳包 socket.sendUrgentData(0x ...

  2. Win8 app判断网络连接状态

    Win8 app判断网络连接状态 NetworkInformation.NetworkStatusChanged += NetworkInformation_NetworkStatusChanged; ...

  3. c#判断网络连接状态示例代码

    使用c#判断网络连接状态的代码. 代码: public partial class Form1 : Form { [DllImport() == true) { label1.Text = " ...

  4. 如何判断Socket连接失效

    http://cuisuqiang.iteye.com/blog/1453632 ——————————————————————————————————————————————————————————— ...

  5. 【Android进阶】判断网络连接状态并自动界面跳转

    用于判断软件打开时的网络连接状态,若无网络连接,提醒用户跳转到设置界面 /** * 设置在onStart()方法里面,可以在界面每次获得焦点的时候都进行检测 */ @Override protecte ...

  6. android判断网络连接状态、联网类型、运营商

    /** * 获取上网方式 * * @param mContext * @return */ public static String getNetType(Context mContext) { St ...

  7. iOS 判断网络连接状态的几种方法

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "PingFang SC"; color: #801b80 } p.p2 ...

  8. iOSReachability判断网络连接状态

    // //  NetStateManage.h // //  Created by miniu on 15/11/24. //  Copyright © 2015年 mini. All rights ...

  9. Android判断网络连接状态

    有的时候我们的应用可能需要判断当前设备是否联网 private void init() { /** 获得系统级联网管理员对象 */ ConnectivityManager manager = (Con ...

随机推荐

  1. WebService 之 属性详解

    WebService 主要包含 WebService .SoapDocumentService.WebServiceBinding三个属性.若要允许使用 ASP.NET AJAX 从脚本中调用此 We ...

  2. xcode 模拟器,文档,离线安装

    一:xcode上的模拟器,文档,在下载时,通过apple.com下载的速度太慢了,所以我们下载之后,做一下备份,离线安装还原就行了! 二:模拟器安装 目录:/Users/<user name&g ...

  3. function(window, undefined)的意义

    var num = 10000 for (var i = 0; i++; i < num) { eval("pp" + i + "=" + i); } ( ...

  4. 通过源码浅析Java中的资源加载

    前提 最近在做一个基础组件项目刚好需要用到JDK中的资源加载,这里说到的资源包括类文件和其他静态资源,刚好需要重新补充一下类加载器和资源加载的相关知识,整理成一篇文章. 理解类的工作原理 这一节主要分 ...

  5. JavaScript中字符串的match与replace方法

    1.match方法 match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配. match()方法的返回值为:存放匹配结果的数组. 2.replace方法 replace() 方 ...

  6. 跟踪数据库中执行时间超过1.5秒的语句及SP,导入数据库

    跟踪 --============================================================================ --新建两个目录 D:\InOut\ ...

  7. ‘close’ was not declared in this scope

    ‘close’ was not declared in this scope ‘read’ was not declared in this scope ‘sysconf’ was not decla ...

  8. 【Linux】more命令

    用途 more主要用于一页一页查看档案 全称 全称即为more 说明 空格键 :代表向下翻一页,也可以使用CTRL+F Enter :代表下翻一行 :f      :立刻显示出文件名以及目前显示的行数 ...

  9. Linux 网桥配置命令:brctl

    Linux网关模式下将有线LAN和无线LAN共享网段实现局域网内互联: 思路其实很简单:就是将虚拟出一个bridge口,将对应的有线LAN和无线LAN都绑定在这个虚拟bridge口上,并给这个brid ...

  10. 转:【微信小程序】实现锚点定位楼层跳跃的实例

    微信小程序实现楼层锚点跳跃,点击不同的锚点进行位置跳跃:  利用:scroll-into-view 来实现: 效果图:   wxml: <scroll-view class="cont ...