socket选项自带的TCP异常断开检测

原创 2011年01月25日 12:51:00

  TCP异常断开是指在突然断电,直接拔网线等等情况下,如果通信双方没有进行数据发送通信等处理的时候,无法获知连接已经断开的情况.

  在通常的情况下,为了使得socket通信不受操作系统的限制,需要自己在应用层实现心跳包机制,来检查异常断开的情况,一般的方式就是服务器在一段时间没有收到客户端数据包时,定时发包,然后客户端回应,如果已经出现异常断开则服务器接收会返回错误,而客户端在指定时间内没有收到数据包,则主动向服务器发包,得到错误就说明断开.诸如此类的方式就是自己实现的心跳包机制.

  但操作系统本身也自带了一些心跳包机制,这些机制是由socket的TCP栈底层实现的,不会影响应用层通信,也不需要应用层自己处理,发现异常断开可以自行检查出来并返回错误(它的本质也是在空闲时发送心跳包).以下介绍一下Windows以及linux下的方法.

  首先介绍Windows下的方法,该方式要求通信双方必须都是Windows NT以上操作系统(如果是其它版本操作系统,如linux等等,不敢保证100%无效).MSDN中有描述WSAIoctl中的SIO_KEEPALIVE_VALS选项,该选项以及struct tcp_keepalive的定义在MSTCPiP.h有,不进行说明了,直接看代码:

 

    #include <MSTCPiP.h>

 

    DWORD retBytes;
    tcp_keepalive inKeepSetting;
    tcp_keepalive retKeepSetting;

    inKeepSetting.onoff = 1;                //探测次数
    inKeepSetting.keepalivetime = 5500;        // 首次探测开始前的tcp无数据收发空闲时间
    inKeepSetting.keepaliveinterval = 3000;    // 每次探测的间隔时间

    if (WSAIoctl(aptSock, SIO_KEEPALIVE_VALS,
        &inKeepSetting,
        sizeof(inKeepSetting),
        &retKeepSetting,
        sizeof(retKeepSetting),
        &retBytes,
        NULL,
        NULL) != 0)
    {
        printf("WSAIoctl Error: %d/n", WSAGetLastError());
    }

 

  Linux下的方式是通过setsockopt来设置选项,见代码(代码从网络上摘录了部分):

  #include   <netinet/tcp.h>
  ……

 

  #define SOCKET_ERROR (-1)

 

  // 以秒为单位
  int   keepAlive = 1;       //设定KeepAlive
  int   keepIdle = 5;        //首次探测开始前的tcp无数据收发空闲时间
  int   keepInterval = 3;  //每次探测的间隔时间
  int   keepCount = 2;     //探测次数
               
  if(setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(void*)&keepAlive,sizeof(keepAlive)) == SOCKET_ERROR)

      printf("Call setsockopt error, errno is %d/n", errno);


  if(setsockopt(s,SOL_TCP,TCP_KEEPIDLE,(void   *)&keepIdle,sizeof(keepIdle)) == SOCKET_ERROR)

      printf("Call setsockopt error, errno is %d/n", errno);

  if(setsockopt(s,SOL_TCP,TCP_KEEPINTVL,(void   *)&keepInterval,sizeof(keepInterval)) == SOCKET_ERROR)

      printf("Call setsockopt error, errno is %d/n", errno);
               
  if(setsockopt(s,SOL_TCP,TCP_KEEPCNT,(void   *)&keepCount,sizeof(keepCount)) == SOCKET_ERROR)

      printf("Call setsockopt error, errno is %d/n", errno);

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

TCP连接中的异常断开情况处理

1.      TCP连接中可能出现的异常断开情况 假设存在这样一种情况:在两个不同的主机Machine1、Machine2系统上分别运行两个应用程序Application1、Application...
  • wjs1033
  • wjs1033
  • 2014年07月08日 10:25
  • 1883

TCP连接的状态详解以及故障排查

linux查看tcp的状态命令: 1)、netstat -nat 查看TCP各个状态的数量 2)、lsof -i:port 可以检测到打开套接字的状况 3)、 sar -n SOCK 查看tc...
  • hguisu
  • hguisu
  • 2014年08月20日 07:06
  • 116672

TCP连接断开情况处理

linger选项打开时: 被动关闭的一端,检查socket的读状态会返回0,但可读的数据长度为0。可以依据它来快速关闭半关闭的socket连接。 closesocket也不是真正意义上的阻塞,它其实是...

TCP异常断开检测

是一方主机的突然崩溃而另一方无法检测到,以致始终保持着不存在的连接。下面介绍一种方法来检测这种异常断开的情况 1) 在TCP协议中提供了KEEPALIVE检测。该选项使能后,在一个TCP连接...

如何判断socket是否连接,异常断开拔出网线

setSoTimeout public void setSoTimeout(int timeout) throws SocketException 启用/禁用带...

socket异常断开

socket网络异常断开关键字: socket 那网络异常断开原因主要有那些呢?归纳起来主要有以下两种: 1、客户端程序异常。   对于这种情况,我们很好处理,因为客户端程序异常退出会在服务端引发Co...
  • lshtb
  • lshtb
  • 2010年11月11日 19:40
  • 1636

socket用户异常掉线检测

目前主要有三种方法来实现用户掉线检测:SO_KEEPALIVE ,SIO_KEEPALIVE_VALS 和Heart-Beat线程。 下面我就上面的三种方法来做一下介绍。 (1)SO_KEEPAL...

判断TCP连接异常

这阵子突然重新接手做了下关于TCP连接异常中断的检测, 这里的异常中断指的是目标主机断电, 网线被拔等非正常因素.   这个问题已经被处理很多年了, 无非2种基本解决策略:    1. 应用层心跳  ...

切实解决socket连接掉线检测

新公司在做物联网,要做与modbus设备的通讯服务。在过程中除了研究modbus协议外,最麻烦的就是设备在线状态的检测问题。 Socket本身无法很好的捕获连接断开事件,或者说根本没这功能。总不能每...

socket心跳检测和重连小demo

有时候我们的程序要求socket一直保持连接,并且希望在socket断开以后能够重新连接,这个时候就需要用到心跳机制,所谓心跳机制,最简单的做法就是客户端每隔一段时间向服务端发送数据包,为了节约资源我...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:socket选项自带的TCP异常断开检测
举报原因:
原因补充:

(最多只允许输入30个字)