سؤال

I am writing an application, which uses TIdTCPClient to communicated with another application via a socket.

I want the application to try to connect to a certain server until the connection is established (i. e. until the server has gone online).

In order to do this, I wrote following code:

procedure SendingThread.Execute();
var
I : integer;
Test : string;
IsConnected : Boolean;
begin
    TcpClient := TIdTCPClient.Create;
    TcpClient.Host := '127.0.0.1';
    TcpClient.Port := 9999;
    TcpClient.ConnectTimeout := 60000;

    IsConnected := false;
    while not IsConnected do
        begin
        try
            TcpClient.Connect;
            IsConnected := True;
        except
            on E:EIdSocketError do
                IsConnected := false;
        end;
    end;
...
end;

When I run this code with server being offline, I get EIdSocketError with error code 10061. The exception is thrown after TcpClient.Connect;.

How can I modify the code so that this exception in caught in the except cause?

هل كانت مفيدة؟

المحلول 2

There are no code modifications necessary.* Your program is already catching the expected exception.

What you're seeing is the debugger intercepting the exception as soon as it's thrown, before your program gets a chance to see that an exception exists and do anything about it. When the IDE intrerrupts you, it shows a dialog box giving you the option to continue running. Exercise that option, or press the "Run" button after you dismiss the dialog box.

You can configure the debugger to ignore some or all exceptions, which is especially helpful when using Indy, which tends to use exceptions for normal flow control. How to do that has been covered here before.

* Remy's answer describes improvements you can make to your code to catch other possible exceptions.

نصائح أخرى

The code you showed is the correct way to handle your reconnect issue, but there is one small change you need to make to it. Change the except block to catch Exception or EIdException instead of EIdSocketError. EIdSocketError is not the only possible exception that Connect() can raise. For instance, it could raise EIdConnectException or EIdConnectTimeout, neither of which are derived from EIdSocketError.

procedure SendingThread.Execute;
var
  ...
  IsConnected : Boolean;
begin
  ...
  IsConnected := False;
  while (not IsConnected) and (not Terminated) do
  begin
    try
      TcpClient.Connect;
      IsConnected := True;
    except
      on E: Exception do
        IsConnected := False;
    end;
  end;
  ...
end;

You can alternatively just remove the on E clause altogether since it is not doing anything useful. The IsConnected variable is already False when the exception is raised, so there is no need to re-assign it to the same value.

procedure SendingThread.Execute;
var
  ...
  IsConnected : Boolean;
begin
  ...
  IsConnected := false;
  while (not IsConnected) and (not Terminated) do
  begin
    try
      TcpClient.Connect;
      IsConnected := True;
    except
    end;
  end;
  ...
end;

While loop is not necessary here since you are already in a thread execute and this while loop will be executed only once always and if not connected your thread will be in in an indefinite loop.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top