Home > Net >  Client connected to a Server, how to auto restart the TCP socket after failiure?
Client connected to a Server, how to auto restart the TCP socket after failiure?

Time:12-23

We are using a Delphi 10.4 application on a Windows 10 PC. This PC is a Client connected to a Server by a SOCKET connection. How can it auto restart the TCP socket after a failure?

A TIdTCPClient (Indy component) is installed. If the connection failed (when server is switches OFF of a certain time), than communication is not restarting automatically after restarting the Server.

It seems that the Socket connection is blocked or removed after a timeout. Can you explain how this works, and how I can automatically restart the socket?

  • Closing and reopening the socket did not help.
  • How should I kill the socket?

I tried to close and reopen the socket and to free it. But no effect.

CodePudding user response:

use a try-except block to catch any exceptions that occur when the socket is in use. Then, in the except block, you can close the socket and create a new one to replace it.

for example:

procedure TForm1.Button1Click(Sender: TObject);
var
  Socket: TClientSocket;
begin
  Socket := TClientSocket.Create(nil);
  try
    Socket.Host := '127.0.0.1';
    Socket.Port := 8080;
    Socket.Open;
    // use the socket here
  except
    on E: Exception do
    begin
      Socket.Free;
      Socket := TClientSocket.Create(nil);
      // try again
    end;
  end;
end;

CodePudding user response:

Indy uses sockets that operate in blocking mode exclusively. On the client side, there is no event when a connection to a server is lost. The only way to detect that condition is to perform timely read/write operations on the socket and catch any errors that may be raised. It can take a long time for the OS to timeout a dead connection, so you should configure the client's own ReadTimeout as needed.

Once you do detect an error, you can simply close and reopen the client.

However, there is a small caveat. When Indy reads bytes from a socket, they are placed in the connection's InputBuffer until your application code reads them from the connection. After a disconnect occurs, if there are any bytes unread in the InputBuffer, Indy considers the connection to still be "alive", giving you a chance to finish reading from it until the InputBuffer is exhausted. So, if you just close and reopen the connection without clearing the InputBuffer, you may get an "already connected" error, for instance. So, just make sure to Clear() the InputBuffer before reopening the connection again.

  • Related