Indy10 ConnectTimeout minimal value












0














I have a problem regarding the ConnectTimeout from Indy 10's TIdTCPClient.



When setting the ConnectTimeout higher than 125ms the Connect() procedure will block the current thread for 125ms. If it is less than 125ms, it will block for the given time (e.g. it blocks for 30ms if the timeout is set to 30ms). In both cases, the connection is stable and I can transmit and receive data.



Why is the TIdTCPClient behaving like that?



IMHO the Connect() procedure should exit directly after the connection is successfully made and only block the full duration of the timeout if no connection can be opened.



Here's my code for monitoring the duration of the Connect() procedure.

The timer for calling TimerConnectTimer is set to 250ms.



I am using Lazarus v1.6.4 and Indy 10 under Windows 7 Professional.



procedure TForm1.FormCreate(Sender: TObject);
begin
timer := TEpikTimer.create(self);
timer.Clear;
end;

procedure TForm1.TimerConnectTimer(Sender: TObject);
begin
timer.Start;
client := TIdTCPClient.create();
logTime(0);
// Tested with values between 10ms and 1000ms
client.ConnectTimeout := SpinEdit1.Value;
try
logTime(1);
// choose ip and port for a running server
client.connect('192.168.2.51', 9912);
logTime(2);
except

end;

logTime(3);

try
client.Disconnect();
FreeAndNil(client);
except

end;

logTime(4);
timer.Clear;
end;

procedure TForm1.logTime(ch: integer);
begin
StringGrid1.Cells[0, ch] := FormatFloat('0.00', timer.Elapsed*1000);
end;









share|improve this question
























  • Which exact version of Indy 10 are you using? It makes a difference in how ConnectTimeout behaves.
    – Remy Lebeau
    Nov 12 '18 at 19:49










  • I am using Indy version 10.6.2.0.
    – The_Programmer
    Nov 13 '18 at 7:50










  • is it actually .0 (that is VERY old), or is it really a newer version that just doesn't have the SVN revision in its version number? Where did you get Indy from exactly, and when? Since you are using FreePascal, you could just update to the latest snapshot (even install it using Lazarus' OPM).
    – Remy Lebeau
    Nov 13 '18 at 9:02
















0














I have a problem regarding the ConnectTimeout from Indy 10's TIdTCPClient.



When setting the ConnectTimeout higher than 125ms the Connect() procedure will block the current thread for 125ms. If it is less than 125ms, it will block for the given time (e.g. it blocks for 30ms if the timeout is set to 30ms). In both cases, the connection is stable and I can transmit and receive data.



Why is the TIdTCPClient behaving like that?



IMHO the Connect() procedure should exit directly after the connection is successfully made and only block the full duration of the timeout if no connection can be opened.



Here's my code for monitoring the duration of the Connect() procedure.

The timer for calling TimerConnectTimer is set to 250ms.



I am using Lazarus v1.6.4 and Indy 10 under Windows 7 Professional.



procedure TForm1.FormCreate(Sender: TObject);
begin
timer := TEpikTimer.create(self);
timer.Clear;
end;

procedure TForm1.TimerConnectTimer(Sender: TObject);
begin
timer.Start;
client := TIdTCPClient.create();
logTime(0);
// Tested with values between 10ms and 1000ms
client.ConnectTimeout := SpinEdit1.Value;
try
logTime(1);
// choose ip and port for a running server
client.connect('192.168.2.51', 9912);
logTime(2);
except

end;

logTime(3);

try
client.Disconnect();
FreeAndNil(client);
except

end;

logTime(4);
timer.Clear;
end;

procedure TForm1.logTime(ch: integer);
begin
StringGrid1.Cells[0, ch] := FormatFloat('0.00', timer.Elapsed*1000);
end;









share|improve this question
























  • Which exact version of Indy 10 are you using? It makes a difference in how ConnectTimeout behaves.
    – Remy Lebeau
    Nov 12 '18 at 19:49










  • I am using Indy version 10.6.2.0.
    – The_Programmer
    Nov 13 '18 at 7:50










  • is it actually .0 (that is VERY old), or is it really a newer version that just doesn't have the SVN revision in its version number? Where did you get Indy from exactly, and when? Since you are using FreePascal, you could just update to the latest snapshot (even install it using Lazarus' OPM).
    – Remy Lebeau
    Nov 13 '18 at 9:02














0












0








0







I have a problem regarding the ConnectTimeout from Indy 10's TIdTCPClient.



When setting the ConnectTimeout higher than 125ms the Connect() procedure will block the current thread for 125ms. If it is less than 125ms, it will block for the given time (e.g. it blocks for 30ms if the timeout is set to 30ms). In both cases, the connection is stable and I can transmit and receive data.



Why is the TIdTCPClient behaving like that?



IMHO the Connect() procedure should exit directly after the connection is successfully made and only block the full duration of the timeout if no connection can be opened.



Here's my code for monitoring the duration of the Connect() procedure.

The timer for calling TimerConnectTimer is set to 250ms.



I am using Lazarus v1.6.4 and Indy 10 under Windows 7 Professional.



procedure TForm1.FormCreate(Sender: TObject);
begin
timer := TEpikTimer.create(self);
timer.Clear;
end;

procedure TForm1.TimerConnectTimer(Sender: TObject);
begin
timer.Start;
client := TIdTCPClient.create();
logTime(0);
// Tested with values between 10ms and 1000ms
client.ConnectTimeout := SpinEdit1.Value;
try
logTime(1);
// choose ip and port for a running server
client.connect('192.168.2.51', 9912);
logTime(2);
except

end;

logTime(3);

try
client.Disconnect();
FreeAndNil(client);
except

end;

logTime(4);
timer.Clear;
end;

procedure TForm1.logTime(ch: integer);
begin
StringGrid1.Cells[0, ch] := FormatFloat('0.00', timer.Elapsed*1000);
end;









share|improve this question















I have a problem regarding the ConnectTimeout from Indy 10's TIdTCPClient.



When setting the ConnectTimeout higher than 125ms the Connect() procedure will block the current thread for 125ms. If it is less than 125ms, it will block for the given time (e.g. it blocks for 30ms if the timeout is set to 30ms). In both cases, the connection is stable and I can transmit and receive data.



Why is the TIdTCPClient behaving like that?



IMHO the Connect() procedure should exit directly after the connection is successfully made and only block the full duration of the timeout if no connection can be opened.



Here's my code for monitoring the duration of the Connect() procedure.

The timer for calling TimerConnectTimer is set to 250ms.



I am using Lazarus v1.6.4 and Indy 10 under Windows 7 Professional.



procedure TForm1.FormCreate(Sender: TObject);
begin
timer := TEpikTimer.create(self);
timer.Clear;
end;

procedure TForm1.TimerConnectTimer(Sender: TObject);
begin
timer.Start;
client := TIdTCPClient.create();
logTime(0);
// Tested with values between 10ms and 1000ms
client.ConnectTimeout := SpinEdit1.Value;
try
logTime(1);
// choose ip and port for a running server
client.connect('192.168.2.51', 9912);
logTime(2);
except

end;

logTime(3);

try
client.Disconnect();
FreeAndNil(client);
except

end;

logTime(4);
timer.Clear;
end;

procedure TForm1.logTime(ch: integer);
begin
StringGrid1.Cells[0, ch] := FormatFloat('0.00', timer.Elapsed*1000);
end;






connection timeout client freepascal indy10






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 '18 at 19:46









Remy Lebeau

331k18251443




331k18251443










asked Nov 12 '18 at 12:00









The_Programmer

11819




11819












  • Which exact version of Indy 10 are you using? It makes a difference in how ConnectTimeout behaves.
    – Remy Lebeau
    Nov 12 '18 at 19:49










  • I am using Indy version 10.6.2.0.
    – The_Programmer
    Nov 13 '18 at 7:50










  • is it actually .0 (that is VERY old), or is it really a newer version that just doesn't have the SVN revision in its version number? Where did you get Indy from exactly, and when? Since you are using FreePascal, you could just update to the latest snapshot (even install it using Lazarus' OPM).
    – Remy Lebeau
    Nov 13 '18 at 9:02


















  • Which exact version of Indy 10 are you using? It makes a difference in how ConnectTimeout behaves.
    – Remy Lebeau
    Nov 12 '18 at 19:49










  • I am using Indy version 10.6.2.0.
    – The_Programmer
    Nov 13 '18 at 7:50










  • is it actually .0 (that is VERY old), or is it really a newer version that just doesn't have the SVN revision in its version number? Where did you get Indy from exactly, and when? Since you are using FreePascal, you could just update to the latest snapshot (even install it using Lazarus' OPM).
    – Remy Lebeau
    Nov 13 '18 at 9:02
















Which exact version of Indy 10 are you using? It makes a difference in how ConnectTimeout behaves.
– Remy Lebeau
Nov 12 '18 at 19:49




Which exact version of Indy 10 are you using? It makes a difference in how ConnectTimeout behaves.
– Remy Lebeau
Nov 12 '18 at 19:49












I am using Indy version 10.6.2.0.
– The_Programmer
Nov 13 '18 at 7:50




I am using Indy version 10.6.2.0.
– The_Programmer
Nov 13 '18 at 7:50












is it actually .0 (that is VERY old), or is it really a newer version that just doesn't have the SVN revision in its version number? Where did you get Indy from exactly, and when? Since you are using FreePascal, you could just update to the latest snapshot (even install it using Lazarus' OPM).
– Remy Lebeau
Nov 13 '18 at 9:02




is it actually .0 (that is VERY old), or is it really a newer version that just doesn't have the SVN revision in its version number? Where did you get Indy from exactly, and when? Since you are using FreePascal, you could just update to the latest snapshot (even install it using Lazarus' OPM).
– Remy Lebeau
Nov 13 '18 at 9:02












1 Answer
1






active

oldest

votes


















0















When setting the ConnectTimeout higher than 125ms the Connect() procedure will block the current thread for 125ms. If it is less than 125ms, it will block for the given time (e.g. it blocks for 30ms if the timeout is set to 30ms). In both cases, the connection is stable and I can transmit and receive data.



Why is the TIdTCPClient behaving like that?




That is hard to answer without knowing which version of Indy 10 you are using exactly, as the implementation of ConnectTimeout has changed over the years. But, in general:



If ConnectTimeout is set to IdTimeoutDefault or 0, IdTimeoutInfinite is used instead.



If Connect() is called in the main UI thread, TIdAntiFreeze is being used, and an infinite timeout is used, a hard-coded 2min timeout is used instead.



If any timeout is used, Connect() spawns a worker thread to connect the socket to the server, and then waits up to the timeout for the thread to terminate. If the timeout elapses before the thread terminates, Indy closes the socket and terminates the thread.



Assuming you are using a fairly up-to-date version of Indy 10 (at least SVN revision 5382 on Dec 14 2016, or later), and are not using TIdAntiFreeze, then on Windows only, the wait should exit immediately when the worker thread terminates, as Indy makes a single call to WaitForSingleObject() on the thread for the full timeout and exits as soon as WFSO exits.



If you are using TIdAntiFreeze, or are using Indy on a non-Windows platform, or are using a version of Indy 10 prior to SVN rev 5382, the wait calls IndySleep() (and if needed, TIdAntiFreeze.DoProcess()) in a loop at fixed intervals (125ms, or TIdAntiFreeze.IdleTimeOut, whichever is smaller) until the timeout is exceeded or the thread has terminated. In which case, there may be a slight delay before Connect() exits, as each sleep cycle has to complete before Connect() can check if the thread has terminated, and do so for every sleep interval within the overall connect timeout.




IMHO the Connect() procedure should exit directly after the connection is successfully made and only block the full duration of the timeout if no connection can be opened.




That is exactly what it currently does, on Windows at least. If the connection is successful, the thread terminates, and Connect() exits immediately (even if TIdAntiFreeze is used). The current sleep cycle is ended by the thread terminating itself. That is not the case on non-Windows platforms (for now, may be addressed in a future version).



Note that all of the above only applies when a timeout is used. If no timeout is used, no worker thread is used, either. Connect() simply connects the socket directly and lets the attempt block the calling thread until finished, whether successful or not.




Here's my code for monitoring the duration of the Connect() procedure.




I would suggest something more like this instead:



procedure TForm1.TimerConnectTimer(Sender: TObject);
begin
try
timer.Start;
try
logTime(0);

client := TIdTCPClient.create();
try
// choose ip and port for a running server
client.Host := '192.168.2.51';
client.Post := 9912;

// Tested with values between 10ms and 1000ms
client.ConnectTimeout := SpinEdit1.Value;

logTime(1);
client.Connect();
logTime(2);
client.Disconnect();
logTime(3);

finally
FreeAndNil(client);
end;

logTime(4);
finally
timer.Clear;
end;
except
end;
end;





share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53261747%2findy10-connecttimeout-minimal-value%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0















    When setting the ConnectTimeout higher than 125ms the Connect() procedure will block the current thread for 125ms. If it is less than 125ms, it will block for the given time (e.g. it blocks for 30ms if the timeout is set to 30ms). In both cases, the connection is stable and I can transmit and receive data.



    Why is the TIdTCPClient behaving like that?




    That is hard to answer without knowing which version of Indy 10 you are using exactly, as the implementation of ConnectTimeout has changed over the years. But, in general:



    If ConnectTimeout is set to IdTimeoutDefault or 0, IdTimeoutInfinite is used instead.



    If Connect() is called in the main UI thread, TIdAntiFreeze is being used, and an infinite timeout is used, a hard-coded 2min timeout is used instead.



    If any timeout is used, Connect() spawns a worker thread to connect the socket to the server, and then waits up to the timeout for the thread to terminate. If the timeout elapses before the thread terminates, Indy closes the socket and terminates the thread.



    Assuming you are using a fairly up-to-date version of Indy 10 (at least SVN revision 5382 on Dec 14 2016, or later), and are not using TIdAntiFreeze, then on Windows only, the wait should exit immediately when the worker thread terminates, as Indy makes a single call to WaitForSingleObject() on the thread for the full timeout and exits as soon as WFSO exits.



    If you are using TIdAntiFreeze, or are using Indy on a non-Windows platform, or are using a version of Indy 10 prior to SVN rev 5382, the wait calls IndySleep() (and if needed, TIdAntiFreeze.DoProcess()) in a loop at fixed intervals (125ms, or TIdAntiFreeze.IdleTimeOut, whichever is smaller) until the timeout is exceeded or the thread has terminated. In which case, there may be a slight delay before Connect() exits, as each sleep cycle has to complete before Connect() can check if the thread has terminated, and do so for every sleep interval within the overall connect timeout.




    IMHO the Connect() procedure should exit directly after the connection is successfully made and only block the full duration of the timeout if no connection can be opened.




    That is exactly what it currently does, on Windows at least. If the connection is successful, the thread terminates, and Connect() exits immediately (even if TIdAntiFreeze is used). The current sleep cycle is ended by the thread terminating itself. That is not the case on non-Windows platforms (for now, may be addressed in a future version).



    Note that all of the above only applies when a timeout is used. If no timeout is used, no worker thread is used, either. Connect() simply connects the socket directly and lets the attempt block the calling thread until finished, whether successful or not.




    Here's my code for monitoring the duration of the Connect() procedure.




    I would suggest something more like this instead:



    procedure TForm1.TimerConnectTimer(Sender: TObject);
    begin
    try
    timer.Start;
    try
    logTime(0);

    client := TIdTCPClient.create();
    try
    // choose ip and port for a running server
    client.Host := '192.168.2.51';
    client.Post := 9912;

    // Tested with values between 10ms and 1000ms
    client.ConnectTimeout := SpinEdit1.Value;

    logTime(1);
    client.Connect();
    logTime(2);
    client.Disconnect();
    logTime(3);

    finally
    FreeAndNil(client);
    end;

    logTime(4);
    finally
    timer.Clear;
    end;
    except
    end;
    end;





    share|improve this answer


























      0















      When setting the ConnectTimeout higher than 125ms the Connect() procedure will block the current thread for 125ms. If it is less than 125ms, it will block for the given time (e.g. it blocks for 30ms if the timeout is set to 30ms). In both cases, the connection is stable and I can transmit and receive data.



      Why is the TIdTCPClient behaving like that?




      That is hard to answer without knowing which version of Indy 10 you are using exactly, as the implementation of ConnectTimeout has changed over the years. But, in general:



      If ConnectTimeout is set to IdTimeoutDefault or 0, IdTimeoutInfinite is used instead.



      If Connect() is called in the main UI thread, TIdAntiFreeze is being used, and an infinite timeout is used, a hard-coded 2min timeout is used instead.



      If any timeout is used, Connect() spawns a worker thread to connect the socket to the server, and then waits up to the timeout for the thread to terminate. If the timeout elapses before the thread terminates, Indy closes the socket and terminates the thread.



      Assuming you are using a fairly up-to-date version of Indy 10 (at least SVN revision 5382 on Dec 14 2016, or later), and are not using TIdAntiFreeze, then on Windows only, the wait should exit immediately when the worker thread terminates, as Indy makes a single call to WaitForSingleObject() on the thread for the full timeout and exits as soon as WFSO exits.



      If you are using TIdAntiFreeze, or are using Indy on a non-Windows platform, or are using a version of Indy 10 prior to SVN rev 5382, the wait calls IndySleep() (and if needed, TIdAntiFreeze.DoProcess()) in a loop at fixed intervals (125ms, or TIdAntiFreeze.IdleTimeOut, whichever is smaller) until the timeout is exceeded or the thread has terminated. In which case, there may be a slight delay before Connect() exits, as each sleep cycle has to complete before Connect() can check if the thread has terminated, and do so for every sleep interval within the overall connect timeout.




      IMHO the Connect() procedure should exit directly after the connection is successfully made and only block the full duration of the timeout if no connection can be opened.




      That is exactly what it currently does, on Windows at least. If the connection is successful, the thread terminates, and Connect() exits immediately (even if TIdAntiFreeze is used). The current sleep cycle is ended by the thread terminating itself. That is not the case on non-Windows platforms (for now, may be addressed in a future version).



      Note that all of the above only applies when a timeout is used. If no timeout is used, no worker thread is used, either. Connect() simply connects the socket directly and lets the attempt block the calling thread until finished, whether successful or not.




      Here's my code for monitoring the duration of the Connect() procedure.




      I would suggest something more like this instead:



      procedure TForm1.TimerConnectTimer(Sender: TObject);
      begin
      try
      timer.Start;
      try
      logTime(0);

      client := TIdTCPClient.create();
      try
      // choose ip and port for a running server
      client.Host := '192.168.2.51';
      client.Post := 9912;

      // Tested with values between 10ms and 1000ms
      client.ConnectTimeout := SpinEdit1.Value;

      logTime(1);
      client.Connect();
      logTime(2);
      client.Disconnect();
      logTime(3);

      finally
      FreeAndNil(client);
      end;

      logTime(4);
      finally
      timer.Clear;
      end;
      except
      end;
      end;





      share|improve this answer
























        0












        0








        0







        When setting the ConnectTimeout higher than 125ms the Connect() procedure will block the current thread for 125ms. If it is less than 125ms, it will block for the given time (e.g. it blocks for 30ms if the timeout is set to 30ms). In both cases, the connection is stable and I can transmit and receive data.



        Why is the TIdTCPClient behaving like that?




        That is hard to answer without knowing which version of Indy 10 you are using exactly, as the implementation of ConnectTimeout has changed over the years. But, in general:



        If ConnectTimeout is set to IdTimeoutDefault or 0, IdTimeoutInfinite is used instead.



        If Connect() is called in the main UI thread, TIdAntiFreeze is being used, and an infinite timeout is used, a hard-coded 2min timeout is used instead.



        If any timeout is used, Connect() spawns a worker thread to connect the socket to the server, and then waits up to the timeout for the thread to terminate. If the timeout elapses before the thread terminates, Indy closes the socket and terminates the thread.



        Assuming you are using a fairly up-to-date version of Indy 10 (at least SVN revision 5382 on Dec 14 2016, or later), and are not using TIdAntiFreeze, then on Windows only, the wait should exit immediately when the worker thread terminates, as Indy makes a single call to WaitForSingleObject() on the thread for the full timeout and exits as soon as WFSO exits.



        If you are using TIdAntiFreeze, or are using Indy on a non-Windows platform, or are using a version of Indy 10 prior to SVN rev 5382, the wait calls IndySleep() (and if needed, TIdAntiFreeze.DoProcess()) in a loop at fixed intervals (125ms, or TIdAntiFreeze.IdleTimeOut, whichever is smaller) until the timeout is exceeded or the thread has terminated. In which case, there may be a slight delay before Connect() exits, as each sleep cycle has to complete before Connect() can check if the thread has terminated, and do so for every sleep interval within the overall connect timeout.




        IMHO the Connect() procedure should exit directly after the connection is successfully made and only block the full duration of the timeout if no connection can be opened.




        That is exactly what it currently does, on Windows at least. If the connection is successful, the thread terminates, and Connect() exits immediately (even if TIdAntiFreeze is used). The current sleep cycle is ended by the thread terminating itself. That is not the case on non-Windows platforms (for now, may be addressed in a future version).



        Note that all of the above only applies when a timeout is used. If no timeout is used, no worker thread is used, either. Connect() simply connects the socket directly and lets the attempt block the calling thread until finished, whether successful or not.




        Here's my code for monitoring the duration of the Connect() procedure.




        I would suggest something more like this instead:



        procedure TForm1.TimerConnectTimer(Sender: TObject);
        begin
        try
        timer.Start;
        try
        logTime(0);

        client := TIdTCPClient.create();
        try
        // choose ip and port for a running server
        client.Host := '192.168.2.51';
        client.Post := 9912;

        // Tested with values between 10ms and 1000ms
        client.ConnectTimeout := SpinEdit1.Value;

        logTime(1);
        client.Connect();
        logTime(2);
        client.Disconnect();
        logTime(3);

        finally
        FreeAndNil(client);
        end;

        logTime(4);
        finally
        timer.Clear;
        end;
        except
        end;
        end;





        share|improve this answer













        When setting the ConnectTimeout higher than 125ms the Connect() procedure will block the current thread for 125ms. If it is less than 125ms, it will block for the given time (e.g. it blocks for 30ms if the timeout is set to 30ms). In both cases, the connection is stable and I can transmit and receive data.



        Why is the TIdTCPClient behaving like that?




        That is hard to answer without knowing which version of Indy 10 you are using exactly, as the implementation of ConnectTimeout has changed over the years. But, in general:



        If ConnectTimeout is set to IdTimeoutDefault or 0, IdTimeoutInfinite is used instead.



        If Connect() is called in the main UI thread, TIdAntiFreeze is being used, and an infinite timeout is used, a hard-coded 2min timeout is used instead.



        If any timeout is used, Connect() spawns a worker thread to connect the socket to the server, and then waits up to the timeout for the thread to terminate. If the timeout elapses before the thread terminates, Indy closes the socket and terminates the thread.



        Assuming you are using a fairly up-to-date version of Indy 10 (at least SVN revision 5382 on Dec 14 2016, or later), and are not using TIdAntiFreeze, then on Windows only, the wait should exit immediately when the worker thread terminates, as Indy makes a single call to WaitForSingleObject() on the thread for the full timeout and exits as soon as WFSO exits.



        If you are using TIdAntiFreeze, or are using Indy on a non-Windows platform, or are using a version of Indy 10 prior to SVN rev 5382, the wait calls IndySleep() (and if needed, TIdAntiFreeze.DoProcess()) in a loop at fixed intervals (125ms, or TIdAntiFreeze.IdleTimeOut, whichever is smaller) until the timeout is exceeded or the thread has terminated. In which case, there may be a slight delay before Connect() exits, as each sleep cycle has to complete before Connect() can check if the thread has terminated, and do so for every sleep interval within the overall connect timeout.




        IMHO the Connect() procedure should exit directly after the connection is successfully made and only block the full duration of the timeout if no connection can be opened.




        That is exactly what it currently does, on Windows at least. If the connection is successful, the thread terminates, and Connect() exits immediately (even if TIdAntiFreeze is used). The current sleep cycle is ended by the thread terminating itself. That is not the case on non-Windows platforms (for now, may be addressed in a future version).



        Note that all of the above only applies when a timeout is used. If no timeout is used, no worker thread is used, either. Connect() simply connects the socket directly and lets the attempt block the calling thread until finished, whether successful or not.




        Here's my code for monitoring the duration of the Connect() procedure.




        I would suggest something more like this instead:



        procedure TForm1.TimerConnectTimer(Sender: TObject);
        begin
        try
        timer.Start;
        try
        logTime(0);

        client := TIdTCPClient.create();
        try
        // choose ip and port for a running server
        client.Host := '192.168.2.51';
        client.Post := 9912;

        // Tested with values between 10ms and 1000ms
        client.ConnectTimeout := SpinEdit1.Value;

        logTime(1);
        client.Connect();
        logTime(2);
        client.Disconnect();
        logTime(3);

        finally
        FreeAndNil(client);
        end;

        logTime(4);
        finally
        timer.Clear;
        end;
        except
        end;
        end;






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 12 '18 at 20:39









        Remy Lebeau

        331k18251443




        331k18251443






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53261747%2findy10-connecttimeout-minimal-value%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Xamarin.form Move up view when keyboard appear

            Post-Redirect-Get with Spring WebFlux and Thymeleaf

            Anylogic : not able to use stopDelay()