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

简介: TCP异常断开是指在突然断电,直接拔网线等等情况下,如果通信双方没有进行数据发送通信等处理的时候,无法获知连接已经断开的情况.   在通常的情况下,为了使得socket通信不受操作系统的限制,需要自己在应用层实现心跳包机制,来检查异常断开的情况,一般的方式就是服务器在一段时间没有收到客户端数据包时...

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);

目录
相关文章
|
3月前
|
缓存 网络协议 算法
提高服务端性能的几个socket选项
提高服务端性能的几个socket选项
104 3
|
5月前
|
网络协议 安全 Java
Java网络编程入门涉及TCP/IP协议理解与Socket通信。
【6月更文挑战第21天】Java网络编程入门涉及TCP/IP协议理解与Socket通信。TCP/IP协议包括应用层、传输层、网络层和数据链路层。使用Java的`ServerSocket`和`Socket`类,服务器监听端口,接受客户端连接,而客户端连接指定服务器并交换数据。基础示例展示如何创建服务器和发送消息。进阶可涉及多线程、NIO和安全传输。学习这些基础知识能助你构建网络应用。
48 1
|
5月前
|
开发框架 网络协议 Unix
【嵌入式软件工程师面经】Socket,TCP,HTTP之间的区别
【嵌入式软件工程师面经】Socket,TCP,HTTP之间的区别
61 1
|
1月前
|
网络协议 Linux 网络性能优化
Linux基础-socket详解、TCP/UDP
综上所述,Linux下的Socket编程是网络通信的重要组成部分,通过灵活运用TCP和UDP协议,开发者能够构建出满足不同需求的网络应用程序。掌握这些基础知识,是进行更复杂网络编程任务的基石。
84 1
|
3月前
|
网络协议 Java
一文讲明TCP网络编程、Socket套接字的讲解使用、网络编程案例
这篇文章全面讲解了基于Socket的TCP网络编程,包括Socket基本概念、TCP编程步骤、客户端和服务端的通信过程,并通过具体代码示例展示了客户端与服务端之间的数据通信。同时,还提供了多个案例分析,如客户端发送信息给服务端、客户端发送文件给服务端以及服务端保存文件并返回确认信息给客户端的场景。
一文讲明TCP网络编程、Socket套接字的讲解使用、网络编程案例
|
2月前
|
网络协议 Linux
TCP 和 UDP 的 Socket 调用
【9月更文挑战第6天】
|
3月前
|
网络协议
socket编程(2) -- TCP通信
socket编程(2) -- TCP通信
39 0
|
4月前
|
网络协议 Java
如何在Java中使用Socket编程实现TCP连接?
在Java中,通过Socket编程实现TCP连接非常常见。以下演示了基本的TCP通信流程,可根据具体需求进行扩展。
242 0
|
5月前
|
监控 网络协议 Java
Java Socket编程 - 基于TCP方式的二进制文件传输
Java Socket编程 - 基于TCP方式的二进制文件传输
46 0
|
5月前
|
网络协议 Java
Java Socket编程 - 基于TCP方式的客户服务器聊天程序
Java Socket编程 - 基于TCP方式的客户服务器聊天程序
56 0