user Windows, IdWinsock2, IdTCPConnection;
private
FSection: TRTLCriticalSection; //临界区
procedure ClientDisconnectEvent(Sender: TObject); // 客户端异常出错处理,需要引用windows单元
procedure T****.CMServerConnect(DSConnectEventObject: TDSConnectEventObject);
var
ClientConnection: TIdTCPConnection;
val: TCP_KeepAlive;
Ret: Integer;
begin
InitializeCriticalSection(FSection); //初始化临界区
EnterCriticalSection(FSection); //进入临界区
if DSConnectEventObject.ChannelInfo <> nil then
begin
ClientConnection := TIdTCPConnection(DSConnectEventObject.ChannelInfo.Id);
ClientConnection.OnDisconnected := ClientDisconnectEvent; // 异常退出,这句是关键
// 设置心跳包,如果不能运行,要引用winsock2单元
val.OnOff := 1;
val.KeepAliveTime := 5000;
val.KeepAliveInterval := 3000;
WSAIoctl(ClientConnection.Socket.Binding.Handle, IOC_IN or IOC_VENDOR or 4,
@val, SizeOf(val), nil, 0, @Ret, nil, nil);
end;
LeaveCriticalSection(FSection);
end;
procedure T****.ClientDisconnectEvent(Sender: TObject);
var
ClientConnection: TIdTCPConnection;
ClientID: Integer;
begin
EnterCriticalSection(FSection);
ClientConnection := Sender as TIdTCPConnection;
ClientID := Integer(ClientConnection);
LeaveCriticalSection(FSection);//离开临界区
DeleteCriticalSection(FSection);//删除临界区
end;