TidTCPClient and ConnectionTimeOut don't Work correctly

Hi, when i try to connect to a server with a TidTCPClient and the server is not found, my app is locked, why?
function TfrmMain.ConnectToServer: Boolean;
var
  LServerResponding: string;
begin
  {Initialization}
  Result := False;
  try
    {Connect to Server}
    with tcpClient do begin
      ConnectTimeout := 1000;
      ReadTimeout := 1000;
      Connect(Server_Host, Server_PortTCPIP);  // THE PROGRAM LOCK HERE
 
      IOHandler.WriteLn('myRequest');
      LServerResponding := IOHandler.ReadLn(LF, TCPIP_TIMEOUT);
      if LServerResponding <> TCPIP_RESP_OK then
        raise Exception.Create('Communication error.')
      else
        Result := True;
    end;
  except
  end;
end;

Open in new window

carmas123Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

2266180Commented:
here is my test code using indy 10.2.3
needless to say, it works. can you run this exact same code and tell me if it locks forever or not in your case?

note that somegarbagedomain.com does not exist, which is your intended scenario.
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdTcpClient;
 
type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    tcpClient:TIdTcpClient;
    function ConnectToServer: Boolean;
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
function TForm1.ConnectToServer: Boolean;
var
  LServerResponding: string;
begin
  {Initialization}
  Result := False;
  try
    {Connect to Server}
    with tcpClient do
    begin
      ConnectTimeout := 1000;
      ReadTimeout := 1000;
      Connect('somegarbagedomain.com', 1054);  // THE PROGRAM LOCK HERE
 
      IOHandler.WriteLn('myRequest');
      LServerResponding := IOHandler.ReadLn(#10, 1000);
      if LServerResponding <> 'ok' then
        raise Exception.Create('Communication error.')
      else
        Result := True;
    end;
  except
  end;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  tcpclient:=TIdTcpClient.create(self);
  showmessage('connected to server? '+booltostr(ConnectToServer, true));
end;
 
end.

Open in new window

0
carmas123Author Commented:
Oh yes this work fine, but if I start this with a TTimer to start the connection with a delay time it won't work.

procedure TForm1.FormCreate(Sender: TObject);
begin
  tcpclient:=TIdTcpClient.create(self);
  myTimer:=TTimer.Create(Self);
  myTimer.Enabled := False;
  myTimer.Interval := 1000;
  myTimer.OnTimer := TimerToConnect;
  myTimer.Enabled := True;
end;
 
procedure TForm1.TimerToConnect(Sender: TObject);
begin
myTimer.Enabled:=False;
  showmessage('connected to server? '+booltostr(ConnectToServer, true));
end;

Open in new window

0
2266180Commented:
are you sure that is the exact code? because it works for me. which is normal, since if it works with no timer, it will work with timer as well.
what's your indy version?
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdTcpClient, ExtCtrls;
 
type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    tcpClient:TIdTcpClient;
    myTimer:TTimer;
    function ConnectToServer: Boolean;
    procedure TimerToConnect(Sender: TObject);
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
const lf=#10;
 
function TForm1.ConnectToServer: Boolean;
var
  LServerResponding: string;
begin
  {Initialization}
  Result := False;
  try
    {Connect to Server}
    with tcpClient do
    begin
      ConnectTimeout := 1000;
      ReadTimeout := 1000;
      Connect('somegarbagedomain.com', 1054);  // THE PROGRAM LOCK HERE
 
      IOHandler.WriteLn('myRequest');
      LServerResponding := IOHandler.ReadLn(LF, 1000);
      if LServerResponding <> 'ok' then
        raise Exception.Create('Communication error.')
      else
        Result := True;
    end;
  except
  end;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  tcpclient:=TIdTcpClient.create(self);
  myTimer:=TTimer.Create(Self);
  myTimer.Enabled := False;
  myTimer.Interval := 1000;
  myTimer.OnTimer := TimerToConnect;
  myTimer.Enabled := True;
end;
 
procedure TForm1.TimerToConnect(Sender: TObject);
begin
  myTimer.Enabled:=False;
  showmessage('connected to server? '+booltostr(ConnectToServer, true));
end;
 
end.

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Introduction to Web Design

Develop a strong foundation and understanding of web design by learning HTML, CSS, and additional tools to help you develop your own website.

carmas123Author Commented:
My Indy version is 10.1.5
0
2266180Commented:
10.1.5 is full of bugs. and when I say full, I really mean full. there were a lot of issues reported with different components and different behaviours, many of them right here on EE.
I strongly suggest you upgrade to latest version. it's the only viable solution.
0
carmas123Author Commented:
Ok now i've installed the 10.2.3 version but the problem is not solved!!
I've, with debug, found where the program is locked.
The program lock when the command WaitFor in procedure DoConnectTimeout(ConnectTimeout); is executed.

I attach the source indy code where i've found the problem.
  procedure DoConnectTimeout(ATimeout: Integer);
  var
    LSleepTime: Integer;
    LInfinite: Boolean;
  begin
    if ATimeout = IdTimeoutDefault then begin
      ATimeout := IdTimeoutInfinite;
    end;
    LInfinite := ATimeout = IdTimeoutInfinite;
    with TIdConnectThread.Create(True) do try
      FBinding := Binding;
      Resume;
      // IndySleep
      if TIdAntiFreezeBase.ShouldUse then begin
        LSleepTime := IndyMin(GAntiFreeze.IdleTimeOut, 125);
      end else begin
        LSleepTime := 125;
      end;
 
      if LInfinite then begin
        ATimeout := LSleepTime + 1;
      end;
 
      while ATimeout > LSleepTime do begin
        IndySleep(LSleepTime);
 
        if LInfinite then begin
          ATimeout := LSleepTime + 1;
        end else begin
          ATimeout := ATimeout - LSleepTime;
        end;
 
        TIdAntiFreezeBase.DoProcess;
        if Terminated then begin
          ATimeout := 0;
          Break;
        end;
      end;
      IndySleep(ATimeout);
      //
      if Terminated then begin
        if FExceptionMessage <> '' then begin
          if FLastSocketError <> 0 then begin
            raise EIdSocketError.CreateError(FLastSocketError, FExceptionMessage);
          end;
          EIdConnectException.Toss(FExceptionMessage);
        end;
      end else begin
        Terminate;
        Close;
        WaitFor;   // THE PROGRAM LOCK HERE!!!
        EIdConnectTimeout.Toss(RSConnectTimeout);
      end;
    finally Free; end;
  end;

Open in new window

0
carmas123Author Commented:
I've been tested that when i try to set ConnectionTimeout to value < 9 (milliseconds) all work fine, if i try to set
the timeout to a >= 10 value, it's wont work.
0
carmas123Author Commented:
I'VE SOLVED TY SO MUCH
0
2266180Commented:
I donwloaded latest 10.2.3 version. tested and it still works. so, I am assuming you are still using the old version.

is the version showmessage displaying 10.2.3 ?
procedure TForm1.FormCreate(Sender: TObject);
begin
  tcpclient:=TIdTcpClient.create(self);
  showmessage(tcpclient.Version);// add this line
  myTimer:=TTimer.Create(Self);

Open in new window

0
2266180Commented:
B grade? did yuo read the grading tips?
0
modus_operandiCommented:
Regraded.
 
modus_operandi
EE Moderator
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.