开发环境:Delphi7

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

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

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

具体实现如下:

TClientSocket和TServerSocket均使用非阻塞模式

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

//定义心跳常量
Const
IOC_IN = $;
IOC_VENDOR = $;
IOC_out = $;
SIO_KEEPALIVE_VALS = IOC_IN or IOC_VENDOR or ;
DATA_BUFSIZE = ; //定义 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 := ;
//需引用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 := ;
klive.keepalivetime := ;
klive.keepaliveinterval := ;
//需引用WinSock2.pas
if WSAIoctl(Socket.SocketHandle, SIO_KEEPALIVE_VALS, PAnsiChar(@klive),
SizeOf(TTCP_KEEPALIVE), PAnsiChar(@outKlive),
SizeOf(TTCP_KEEPALIVE), @opt,,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下载

测试效果图:

Delphi之TClientSocket和TServerSocket使用tcp keepalive心跳机制实现“断网”、"断电"检测的更多相关文章

  1. TCP连接探测中的Keepalive和心跳包. 关键字: tcp keepalive, 心跳, 保活

    1. TCP保活的必要性 1) 很多防火墙等对于空闲socket自动关闭 2) 对于非正常断开, 服务器并不能检测到. 为了回收资源, 必须提供一种检测机制. 2. 导致TCP断连的因素 如果网络正常 ...

  2. 心跳机制tcp keepalive的讨论、应用及“断网”、"断电"检测的C代码实现(Windows环境下)

    版权声明:本文为博主原创文章,转载时请务必注明本文地址, 禁止用于任何商业用途, 否则会用法律维权. https://blog.csdn.net/stpeace/article/details/441 ...

  3. 聊聊TCP Keepalive、Netty和Docker

    聊聊TCP Keepalive.Netty和Docker 本文主要阐述TCP Keepalive和对应的内核参数,及其在Netty,Docker中的实现.简单总结了工作中遇到的问题,与大家共勉. 起因 ...

  4. 一文读懂Android进程及TCP动态心跳保活

    一直以来,APP进程保活都是 各软件提供商 和 个人开发者 头疼的问题.毕竟一切的商业模式都建立在用户对APP的使用上,因此保证APP进程的唤醒,提升用户的使用时间,便是软件提供商和个人开发者的永恒追 ...

  5. delphi安装 Tclientsocket, Tserversocket控件

    菜单component->Install Packets按Add按钮,选择delphi目录里的bin目录下的dclsockets70.bpl(delphi2010是 dclsockets140. ...

  6. TCP keepalive overview

    2. TCP keepalive overview In order to understand what TCP keepalive (which we will just call keepali ...

  7. 【转载】TCP保活(TCP keepalive)

    下图是我遇到tcp keepalive的例子: 以下为转载: TCP保活的缘起 双方建立交互的连接,但是并不是一直存在数据交互,有些连接会在数据交互完毕后,主动释放连接,而有些不会,那么在长时间无数据 ...

  8. TCP keepalive under Linux

    TCP Keepalive HOWTO Prev   Next 3. Using TCP keepalive under Linux Linux has built-in support for ke ...

  9. TCP keepalive

      2. TCP keepalive overview In order to understand what TCP keepalive (which we will just call keepa ...

随机推荐

  1. 编辑docker容器中的文件

    一般docker中没有VI或者其它相应的文本编辑器,为了写个东西安装个vi就可以解决问题,除此之外还有别的办法 登陆docker中找到需要编辑的文件的位置 sudo docker ps -a sudo ...

  2. sql 存储过程笔记2

    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sys_Page_v2]') and OBJECTPROPE ...

  3. Oracle笔记(五) 单行函数

    虽然各个数据库都是支持SQL语句的,但是每一个数据库也有每一个数据库自己所支持的操作函数,这些就是单行函数,而如果要想进行数据库开发的话,除了要会使用SQL之外 ,就是要多学习函数. 单行函数主要分为 ...

  4. FASTCGI/CGI

    在了解这两个协议之前,我们先谈一下动态网页 动态网页 是指跟静态网页相对的一种网页编程技术.静态网页,随着html代码的生成,页面的内容和显示效果就基本上不会发生变化了--除非你修改页面代码.而动态网 ...

  5. Acwing 197. 阶乘分解

    给定整数 N ,试把阶乘 N! 分解质因数,按照算术基本定理的形式输出分解结果中的 pipi 和 cici 即可. 输入格式 一个整数N. 输出格式 N! 分解质因数后的结果,共若干行,每行一对pi, ...

  6. Java常用类(一)Math类和Random类

    一.Math类 Math类中有一些常用的数学函数,比较简单,不进行详细解释,仅举例说明: 1.绝对值和取整 import java.lang.Math; public class Mat { publ ...

  7. Systemd-journalctl日志管理

    Systemd 统一管理所有 Unit 的启动日志.带来的好处就是,可以只用journalctl一个命令,查看所有日志(内核日志和应用日志).日志的配置文件/etc/systemd/journald. ...

  8. linux 发送 post 请求

    curl -H "Content-type: application/json" -X POST -d '{"accoId":"IDAP_000000 ...

  9. Java程序中实现 MySQL数据库的备份与还原

    案例代码: 数据库备份 //mysqldump -h端口号 -u用户 -p密码 数据库 > d:/test.sql --备份D盘 //备份 public static void dataBase ...

  10. BZOJ 4278: [ONTAK2015]Tasowanie (后缀数组 / 二分+hash)

    直接归并,然后如果哪边的后缀字典序比较小就去哪边,然后就可以后缀数组 博客传送门- 但是本蒟蒻不会后缀数组 Upd:Upd:Upd:现在会了233.一道差不多的题:BZOJ 1692: [Usaco2 ...