Search code examples
delphidelphi-2010tcpclientindyindy10

TCPclient.connected problem in Delphi - Indy


I am having problem with IdTCPclient.connected function from Indy in Delphi. I am using Indy10 and Delphi2010 environment. My problem is every time i check the TCP connection with IdTCPclient.connected, it raises exception with these errors EidSocketError, EidReadTimeOut. Is there any way to disconnect and reconnect the connection? (like reset the connection).

Note: I set TCPClient.ReTimeout:= 30000;

The implemented coding for reset the connection is follow.

if IdTCPclient.connected then
  begin
  IdTCPclient.IOHandler.InputBuffer.Clear;
  IdTCPclient.Disconnect;
  end;
sleep(1000);
try
  IdTCPclient.connect;
  except
    on E: Exception do 
      MessageDlg('Connecting Error: '+E.Message, mtError, [mbOk], 0);
  end;

But some point, i get exception and it couldn't connect at all. I am not sure what i am doing wrong.

Should i do this?

  • Disconnect first
  • Clear input buffer
  • Destroy TCPclient
  • Re-create new TCPclient
  • And then connect it again

If it is the case, can someone provide me a way how to do it properly?

Also, there is another function to re-connecting the TCP in my coding. It also gives me exception as well. I check the connecting before i send a message to TCP. If there is no connection, i reconnect for five times.

result := IdTCPclient.connected
if not result then
  begin
  for k:=0 to 4 do
    beign
    sleep(1000);
    try
      TCPclient.connect;
      except
        on E: Exception do 
          MessageDlg('Connecting Error: '+E.Message, mtError, [mbOk], 0);
      end
    result := TCPclient.connected;
    if result then break;
    end;

With above two coding, program handles reconnecting and reset the connection pretty well. But some point the program cannot re-connect or reset the connection at all.

  • What should i do when i get exception? Should i reconnect from exception?
  • How do we build coding to check the connection regularly?
  • How do we build coding to to get back the connection when it lost?

Kind regards,


Solution

  • Connected() should not be raising any exceptions at all. If it is, then it is likely a bug. Please provide a stack trace showing that.

    The best option is to simply avoid using Connected() whenever possible. When you need to perform an I/O operation, just do so, and let Indy raise an exception if a failure occurs. You can then handle it at that moment, eg:

    try
      IdTCPClient.DoSomething...
    except
      on E: EIdException do begin
        Reconnect;
      end;
    end;
    
    procedure Reconnect;
    var
      k: Integer;
    begin
      IdTCPClient.Disconnect;
      if IdTCPClient.IOHandler <> nil then
        IdTCPClient.IOHandler.InputBuffer.Clear;
    
      for k := 0 to 4 do
      begin
        Sleep(1000);
        try
          IdTCPClient.Connect;
          Exit;
        except
          on E: Exception do
          begin
            MessageDlg('Connecting Error: '+E.Message, mtError, [mbOk], 0);
            if k = 4 then
              raise;
          end;
        end;
      end; 
    end;