I have the following code, "adapted" from Lebeau's answer in another post: Delphi XE2 / Indy TIdTCPServer / "Connection reset by peer"
type
TClient = class(TObject)
public
Host: String;
Queue: TIdThreadSafeStringList;
end;
var
Clients: TThreadList;
function TMain.HostOnTList(const Host: String): Pointer;
var
I: Integer;
List: TList;
begin
Result := nil;
List := Clients.LockList;
try
for I := 0 to List.Count - 1 do
if (TClient(List[I]).Host = Host) then
begin
Result := List[I];
Break;
end;
finally
Clients.UnlockList;
end;
end;
procedure TMain.FormCreate(Sender: TObject);
const
Hosts: Array[0..4] of String = (
'HOST1', 'HOST2', 'HOST3', 'HOST4, 'HOST5'
);
var
I: Integer;
List: TList;
Client: TClient;
begin
Clients := TThreadList.Create;
Clients.Duplicates := dupAccept;
for I := Low(Hosts) to High(Hosts) do
begin
Client := TClient.Create;
Client.Host := Hosts[I];
Client.Queue := TIdThreadSafeStringList.Create;
Clients.Add(Client);
Client := nil;
end;
end;
procedure TMain.FormDestroy(Sender: TObject);
var
I: Integer;
List: TList;
begin
if TCPServer.Active Then
TCPServer.Active := False;
List := Clients.LockList;
try
for I := 0 to List.Count - 1 do
TClient(List[I]).Free;
finally
Clients.UnlockList;
Clients.Free;
end;
end;
procedure TMain.TCPServerConnect(AContext: TIdContext);
var
Host: String; // Host String
CIdx: Pointer; // Client Pointer
begin
... (get context hostname)
CIdx := HostOnTList(Host);
if (CIdx <> nil) then
AContext.Data := TClient(CIdx);
else
... (disconnect client)
end;
procedure TMain.TCPServerDisconnect(AContext: TIdContext);
var
List: TList;
Host: String;
Client: TClient;
begin
Host := '';
Client := TClient(AContext.Data);
List := Clients.LockList;
try
Host := Client.Host;
if (Host <> '') then
begin
Client.Queue := nil;
AContext.Data := nil;
end;
finally
Clients.UnlockList;
end;
end;
procedure TMain.idTCPServerExecute(AContext: TIdContext);
var
I: Integer;
List: TStringList;
begin
Client := TClient(AContext.Data);
...
List := Client.Queue.Lock;
try
while List.Count > 0 do
begin
WriteLn(List[0]);
List.Delete(0);
end;
finally
Client.Queue.Unlock;
end;
...
end;
function TMain.SendMessage(const Host, Msg: String): Boolean;
var
List: TList;
CIdx: Pointer;
begin
Result := False;
CIdx := HostOnTList(Host);
if (CIdx <> nil) then
begin
List := TCPServer.Contexts.LockList;
try
TClient(CIdx).Queue.Add(Msg);
Result := True;
finally
TCPServer.Contexts.UnlockList;
end;
end;
end;
But is happening a strange behavior... Client can connect, but once disconnect and try to connect again, it is been disconnected.
I tried to comment the lines of code until find the problem, and it happens with this line: "List := Client.Queue.Lock;" inside idTCPServerExecute procedure.
Please, anyone knows what is going on?
Thanks!