Terminate an inactive socket connection from TIdTCPServer
We have an application which listens for incoming TCP requests using the Indy 10.1.1 components that ship with Delphi 2007.
Occassionally we receive incoming connections which are not from our client application. Typically, one of two things happens: 1) the connec开发者_高级运维tion is terminated by the client before any data is received, or 2) data is received which we're not expecting and we manually terminate the connection.
However, we've received connections where no data is received and appear to persist until the client terminates the connection from their end.
Is there a way to terminate such a connection from the server if no data is received after a specified amount of time?
In your OnExecute event handler, keep track of when the last good data was received from the client. Using the connection's ReadTimeout property, you can timeout pending read operations periodically so you can check if the client has not sent data for awhile, and if so then disconnect it.
Save this as killthread.pas
unit killthread;
interface
uses
Classes, IdTCPServer, IdTCPClient, IdContext, Types, SyncObjs;
type
TKillThread = class(TThread)
private
FContext: TIdContext;
FInterval: DWORD;
FEvent: TEvent;
protected
procedure Execute; override;
public
constructor Create(AContext: TIdContext; AInterval: DWORD); overload;
destructor Destroy; override;
procedure Reset;
procedure Stop;
end;
implementation
{ TKillThread }
constructor TKillThread.Create(AContext: TIdContext; AInterval: DWORD);
begin
FContext := AContext;
FInterval := AInterval;
FEvent := TEvent.Create(nil, False, False, '');
inherited Create(False);
end;
destructor TKillThread.Destroy;
begin
FEvent.Free;
inherited Destroy;
end;
procedure TKillThread.Reset;
begin
FEvent.SetEvent;
end;
procedure TKillThread.Stop;
begin
Terminate;
FEvent.SetEvent;
WaitFor;
end;
procedure TKillThread.Execute;
begin
while not Terminated do
begin
if FEvent.WaitFor(FInterval) = wrTimeout then
begin
FContext.Connection.Disconnect;
Exit;
end;
end;
end;
end.
Then do this on the server side:
procedure TYourTCPServer.OnConnect(AContext: TIdContext);
begin
AContext.Data := TKillThread.Create(AContext, 120000);
end;
procedure TYourTCPServer.OnDisconnect(AContext: TIdContext);
begin
TKillThread(AContext.Data).Stop;
end;
procedure TYourTCPServer.OnExecute(AContext: TIdContext);
begin
if AContext.Connection.Connected then
begin
TKillThread(AContext.Data).Reset;
// your code here
end;
end;
i have similiar problem, i used delphi7+Indy9.
and my solution: in TIdTCPServer event onConnect, i do like this
procedure Tf_main.ServerHostConnect(AThread: TIdPeerThread);
begin
//code something
//mean AThread will do Disconnected if Client no activity ( send receive ) on interval...)
AThread.Connection.ReadTimeout := 300000; //5 minutes..
//code something
end;
maybe on Indy10 you can do similiar like that
You should be able to call (TIdTCPConnection).Disconnect
.
精彩评论