I have a small problem, when connect to server TIdTcpClient generate "Connection Closed Gracefully" error on FConn.IOHandler.ReadLn of procedure TReadingThread.Execute;, that don't happen all time, just some, and if try again and again it don't happen, also don't happen at another VPS where server run. but that's ok.
I did few changes who work arount the error and if error happens it basically disconnect, terminate threads and try again. my question is, what i did can cause some problem or works fine? on tests solved, it failed 8 times and at 9 attempt it connected.
What i did:
procedure TReadingThread.Execute;
var
Recebeu : String;
begin
while not Terminated do
begin
try
Recebeu := FConn.IOHandler.ReadLn;
except
on E: Exception do
begin
THD.Terminate;
FConn.IOHandler.InputBuffer.Clear;
FConn.Disconnect(False);
if rt <> nil then rt.Terminate;
THD := TThreadCon.Create;
THD.Start;
end;
end;
if not Recebeu.IsEmpty then
begin
THD is THD : TThreadCon = nil
procedure TThreadCon.Execute;
var
Attempt : Integer;
begin
Attempt := 0;
try
while not Terminated do
begin
if TCPClient.IOHandler <> nil then TCPClient.IOHandler.InputBuffer.Clear;
try
Inc(Attempt);
TCPClient.Connect;
try
TCPClient.IOHandler.WriteLn('Connect');
except
TCPClient.Disconnect(False);
raise;
end;
except
on E: Exception do
begin
if (Attempt >= 3) then
begin
THD.Terminate;
end;
if FTermEvent.WaitFor(2500) <> wrTimeout then Exit;
Continue;
end;
end;
rt := TReadingThread.Create(TCPClient);
try
try
while not Terminated do
begin
if FTermEvent.WaitFor(5000) <> wrTimeout then Exit;
end;
except
end;
finally
rt.Terminate;
try
TCPClient.Disconnect(False);
finally
rt.WaitFor;
rt.Free;
end;
end;
end;
finally
TCPClient.Free;
end;
end;
As i see, since i declare and Set Attempt at Execute, it never will trigger if (Attempt >= 3) thenon on E: Exception do but that's ok.
Connection Closed Gracefully error happens only if Server closes the connection?
"Connection Closed Gracefully" means the connection was closed intentionally by a remote peer, typically the server yes, but it could also happen if a firewall/router sitting between the client and server closed the connection due to inactivity, etc.
The error is normal on the client side, and your solution is basically correct - close the connection and reconnect.
Although, I do question why you are calling
Connect()andReadLn()in separate threads. That is unusual. Why not call them in a single thread instead? You can have an outer loop that callsConnect()andWriteLn(), and then an inner loop that callsReadLn(), eg: