Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: TIdTcpServer: detect 3rd party dead clients that didnt disconnect correctly



Permlink Replies: 2 - Last Post: Nov 6, 2017 12:04 AM Last Post By: Vincent V.
Vincent V.

Posts: 10
Registered: 1/2/10
TIdTcpServer: detect 3rd party dead clients that didnt disconnect correctly
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 3, 2017 4:08 AM
Hello,

in a server application with a TIdTCPServer, I have a problem that some 3rd client connections are gone without disconnecting (I know from the vendor it happens when they restart their computer). I checked this with Wireshark and saw that the disconnect does not occur, probably their client application crashes during restart.

I managed to reproduce this problem:
-wrote a very small server application (see code below).
-connect to it with telnet from an other pc
-i unplug the switch in between.

-> Result: None of the parties know that the connection is gone. The checks below don't detect this:

procedure TForm1.srvExecute(AContext: TIdContext);
var
  b: Boolean;
begin
  //---
  if doDbg then begin
    b := AContext.Connection.Connected;
    AContext.Connection.CheckForGracefulDisconnect(True);
    b := AContext.Connection.Socket.Connected;
  end;


I know that as soon as the server application will try to send data it will trigger an exception and Indy will close the connection. However, the application level protocol we are using does not allow my server application to send out data regularly as a heartbeat.

-Is there a way to detect that the client is no longer connected, without sending out data? ( I have no control over the client software)
-I'm considering using the TCP keepalives (with GStack.SetSocketOption), is this a good approach or might some hardware / clients act weird when using these?

Regards,
Vincent
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: TIdTcpServer: detect 3rd party dead clients that didnt disconnect correctly
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 3, 2017 1:22 PM   in response to: Vincent V. in response to: Vincent V.
Vincent V. wrote:

-> Result: None of the parties know that the connection is gone. The
checks below don't detect this:

They do, but not for awhile. Abnormal disconnects take time
(potentially a long time) for the OS to timeout the socket internally
and invalidate the connection before any I/O operations start reporting
failures.

The correct way to handle this is to use periodic heartbeats.

Define an explicit heartbeat command in your communication protocol.
Require the client to send that command at regular intervals (when not
sending other commands) to indicate its desired to stay connected. Or
have the server send that command to the client during periods of
idleness and require the client to reply to it. Either way, if the
server does not receive communications from the client after a period
of time, just assume the connection is dead and close it.

If that is not an option, at least enable TCP keep-alives (you can use
the AContext.Binding.SetKeepAliveValues() method for that) so that I/O
operations will fail sooner rather than later on dead connections.

I know that as soon as the server application will try to send data
it will trigger an exception

Yes, but not right away, not until the OS has timed out and invalidated
the socket.

However, the application level protocol we are using does not allow
my server application to send out data regularly as a heartbeat.

Then yo will have to rely on TCP keep-alives.

-Is there a way to detect that the client is no longer connected,
without sending out data?

No. Even TCP keep-alives are sending data, just not data under your
control.

I'm considering using the TCP keepalives (with
GStack.SetSocketOption), is this a good approach

Yes. That is what it is intended for.

or might some hardware / clients act weird when using these?

No, because keepalives are required by the TCP standard to be supported
by all TCP stack implementations.

--
Remy Lebeau (TeamB)
Vincent V.

Posts: 10
Registered: 1/2/10
Re: TIdTcpServer: detect 3rd party dead clients that didnt disconnect correctly
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 6, 2017 12:04 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thank you once again Remy for a very clear and helpful answer!
Vincent
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02