TCPclient.connected problem in Delphi - Indy

11,662

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;
Share:
11,662
sMah
Author by

sMah

Updated on June 04, 2022

Comments

  • sMah
    sMah almost 2 years

    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,

  • Roddy
    Roddy over 10 years
    Similar to the OP, I'm seeing Indy10 Connected() raise an exception. Stack trace here i.imgur.com/F9ejbTl.png?1 No line numbers - sorry!
  • Remy Lebeau
    Remy Lebeau over 10 years
    @Roddy: That does not make sense. ReadDataFromSource() is not called unless the socket is in a readable state first (TIdSocketHandle.Readable() returns True), which can only happen if the socket has actual data to read, or the connection has been gracefully disconnected by the peer. A Receive() should not fail on either of those conditions. What exception is actually being raised, and what socket error code is being reported?
  • Roddy
    Roddy over 10 years
    EIdSocketError, 10054 connection reset by peer. It's definitely odd, but seems repatable. Indy is latest SVN from MJF. I have a 'working' connection, and then pull the plug. The client tries to send data and gets EIdSocketError (which is fine), but in the exception handler I call Connected() which also throws the same exception. Reading is handled by a different thread.
  • Remy Lebeau
    Remy Lebeau over 10 years
    Ah, that explains why Receive() can fail. And it turn out that TIdStackBSDBase.Receive() is calling CheckForSocketError() but TIdIOHandler is expecting to handle the socket error instead (by letting Connected() discard it). I'll have to look into that, I think the TIdStack classes are calling CheckForSocketError() too much in general. In any case, you shouldn't be calling Connected() anyway. You already know the socket is not connected by virtue of the fact that you are getting an EIdSocketError/10054 exception, so calling Connected() would be redundant.
  • Molochnik
    Molochnik about 7 years
    @Remy Once (6 years ago) you said that Connected() from TIdTCPClient should not be raising any exceptions but it is. Is this an old still unresolved bug?
  • Remy Lebeau
    Remy Lebeau about 7 years
    @Molochnik are you saying that the latest SVN revision is still raising the exception? I thought I fixed that years ago.
  • Molochnik
    Molochnik almost 7 years
    @Remy Yes, that's true, I always use your latest (almost) SVN version. Checking my old code I found that it always contains Connected in try-except blocks. Now I tried to eliminate them but exceptions still occur.