zoukankan      html  css  js  c++  java
  • Delphi之TClientSocket和TServerSocket使用tcp keepalive心跳机制实现“断网”、"断电"检测

    开发环境:Delphi7

    测试环境:WinXP,Win7  32bit,Win7 64bit

    使用TClientSocket和TServerSocket实现TCP长连接通讯,经常因为断电断网等原因导致出现一些死连接。

    解决方法是客户端和服务端都定时发送心跳包。

    具体实现如下:

    TClientSocket和TServerSocket均使用非阻塞模式

    1、定义心跳常量和KeepAlive 数据结构

    //定义心跳常量
    Const
      IOC_IN = $80000000;
      IOC_VENDOR = $18000000;
      IOC_out = $40000000;
      SIO_KEEPALIVE_VALS = IOC_IN or IOC_VENDOR or 4;
      DATA_BUFSIZE = 8192;
    
    //定义 KeepAlive 数据结构
    Type
      TTCP_KEEPALIVE = packed record
        onoff: integer;
        keepalivetime: integer;
        keepaliveinterval: integer;
      end;

    2、引用WinSock,WinSock2

    3、写一个方法来使用setsockopt,WSAIoctl设置心跳包参数

    procedure TForm1.setKeepAlive(Socket: TCustomWinSocket);
    var
      opt:Integer;
      klive, outKlive: TTCP_KEEPALIVE;
      i,j:integer;
      OptVal: DWORD;
    begin
      opt := 1;
      //需引用WinSock.pas
      if setsockopt(Socket.SocketHandle,SOL_SOCKET, SO_KEEPALIVE, PAnsiChar(@opt), SizeOf(opt)) = SOCKET_ERROR then
      begin
        showInfo(Format('WinSock Error %d', [WSAGetLastError()]));
      end;
      klive.onoff := 1;
      klive.keepalivetime := 5000;
      klive.keepaliveinterval := 1;
      //需引用WinSock2.pas
      if WSAIoctl(Socket.SocketHandle, SIO_KEEPALIVE_VALS, PAnsiChar(@klive),
               SizeOf(TTCP_KEEPALIVE), PAnsiChar(@outKlive),
               SizeOf(TTCP_KEEPALIVE), @opt,0,nil) = SOCKET_ERROR then
      begin
        showInfo(Format('WinSock Error %d', [WSAGetLastError()]));
      end;
    
    end;

    4、在TClientSocket和TServerSocket的连接事件中调用设置心跳

    procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    begin
      showInfo('ServerSocket1ClientConnect-' + Socket.RemoteAddress + ':' + IntToStr(Socket.RemotePort));
      setKeepAlive(Socket); //设置socket心跳,以便清除死链接
    end;

    经测试,采用以上方法,可以检测到把网线断网情况

    测试demo下载

    测试效果图:

  • 相关阅读:
    《python核心编程第二版》第8章习题
    《python核心编程第二版》第7章习题
    虚拟Ip技术如何实现备机容灾
    LeetCode算法编程连载之五
    GIT使用入门篇(管理自已的代码)
    LeetCode算法编程之连载四(二分法)
    LeetCode算法编程之连载三
    LeetCode算法编程之连载二
    LeetCode算法编程之连载一
    Python 使用flush函数将缓冲区数据立即写磁盘
  • 原文地址:https://www.cnblogs.com/tc310/p/10886086.html
Copyright © 2011-2022 走看看