Board index » delphi » Client Disconnect from Server App that is not running - Sorry Remy - Another One

Client Disconnect from Server App that is not running - Sorry Remy - Another One


2007-04-17 06:06:29 PM
delphi128
I am testing possible broken connection scenarios...
I have a Server App with TidTCPServer running and accepting connections from
TidTCPClient.
After a client has connected I end the Server App by using Win Task Manager
and ending its process.
Now I call TCpCLient.Disconnect, once or twice even and then start the
Server App again.
The problem now is that when I TCPClient.Connect again from the same
client app it will indicate that it is connected but the Server will not
show that it received a connection.
It seems to me that the first instance of the Server App has opened sockets
and they were not closed because I ended that App's process without closing
the app properly and now the Client is connected to those sockets and not
the new instance of the Server.
Is this the case and if so what must I do to reinitialize those sockets when
I run the Server App, so that the Client will connect to the new instance of
the Server App?
Thank you
 
 

Re:Client Disconnect from Server App that is not running - Sorry Remy - Another One

"PeaShooter_OMO" <XXXX@XXXXX.COM>writes
Quote
After a client has connected I end the Server App by using
Win Task Manager and ending its process.
That is an abnormal disconnect. The socket stack on the client side
won't be able to detect that in a timely manner. Are you using
pings/keepalives in your communications?
Quote
The problem now is that when I TCPClient.Connect again
from the same client app it will indicate that it is connected
Are you saying that Connect() exits without raising an exception? I
would expect that since the server is running again.
Or are you saying that Connect() raises an exception saying that it is
already connected and cannot connect again? That could happen if your
server sent any data to the client before shutting down, and then the
client did not process that data before calling Disconnect(), leaving
the data in the connection's InputBuffer.
Quote
but the Server will not show that it received a connection.
Then the client did not actually connect to the server. Or the server
had an internal error that killed the connection before any events
could be triggered for it. Do you have an OnListenException event
handler assigned to the server?
Quote
It seems to me that the first instance of the Server App has opened
sockets and they were not closed because I ended that App's
process without closing the app properly and now the Client is
connected to those sockets and not the new instance of the Server.
If that were true, then the behavior depends on what you have the
server's ReuseSocket property set to. If it is not set to rsTrue, or
is set to rsOSDependent (which is the default) but you are not running
on Linux, then the server would generate errors when the second
instance tries to re-use the old ports again.
Gambit
 

Re:Client Disconnect from Server App that is not running - Sorry Remy - Another One

Quote

>After a client has connected I end the Server App by using
>Win Task Manager and ending its process.

That is an abnormal disconnect. The socket stack on the client side
won't be able to detect that in a timely manner. Are you using
pings/keepalives in your communications?

Abnormal but possible. Its the world of Windows.
I have written a ListenerThread like you advised. And I think its pretty
thorough. Hopefully?!
I test the connection when I want to Send something. When I test the
connection I do the following:
try
// This gives an exception in my case if the app was ended by ending
the process
If FTCPClient.Connected then
FTCPClient.CheckForGracefulDisconnect;
// Otherwise the second line will, of course for graceful
except
FConnected := False;
end;
Quote
>The problem now is that when I TCPClient.Connect again
>from the same client app it will indicate that it is connected

Are you saying that Connect() exits without raising an exception? I
would expect that since the server is running again.

I Disconnect first while I haven't started the second instance of the Server
App yet. SOmetimes doing twice (from a button click)
Then I try Connect again after starting the new instance of the Server app.
This is when the Client shows that I am connected but the new instance of
the Server doesn't show it
Quote
Or are you saying that Connect() raises an exception saying that it is
already connected and cannot connect again? That could happen if your
server sent any data to the client before shutting down, and then the
client did not process that data before calling Disconnect(), leaving
the data in the connection's InputBuffer.

>but the Server will not show that it received a connection.

Then the client did not actually connect to the server. Or the server
had an internal error that killed the connection before any events
could be triggered for it. Do you have an OnListenException event
handler assigned to the server?

>It seems to me that the first instance of the Server App has opened
>sockets and they were not closed because I ended that App's
>process without closing the app properly and now the Client is
>connected to those sockets and not the new instance of the Server.

If that were true, then the behavior depends on what you have the
server's ReuseSocket property set to. If it is not set to rsTrue, or
is set to rsOSDependent (which is the default) but you are not running
on Linux, then the server would generate errors when the second
instance tries to re-use the old ports again.


Gambit


 

Re:Client Disconnect from Server App that is not running - Sorry Remy - Another One

"PeaShooter_OMO" <XXXX@XXXXX.COM>writes
Quote
Abnormal but possible. Its the world of Windows.
I know it is possible. That is not the point I was trying to make. A
socket can not detect an abnormal disconnect until it times out
internally, which unfortunately on Windows can be upwards of several
hours. If a client connects to a server and then the server goes down
unexpectedly, the client won't know right away. On the other hand, if
a client goes down unexpectedly, the server won't know right away.
Either way, you need to implement some kind of system in your
communication protocol for both sides to detect when the other side
has become idle and is no longer responding, so that the socket can be
closed and released gracefully in a timely manner on the side that is
still running.
If you have control over the protocol design, then the easiest way to
implement that is to have the server keep track of when each client
last sent any data to the server, and then disconnect any clients who
are idle for too long a period of time. Then require the clients to
send data to the server periodically for as long as they want to stay
connected, and wait for a reply. This way, the server can disconnect
idle clients, and clients can disconnect from unresponsible servers.
Quote
I have written a ListenerThread like you advised. And I think
its pretty thorough.
It is not thorough.
Quote
I test the connection when I want to Send something. When
I test the connection I do the following:
You should not be doing that. Indy already does that internally for
you. Just send normally, and then catch any error that may occur.
Quote
This gives an exception in my case if the app was ended by ending
the process
Not right away, it doesn't, because the OS doesn't keep track of that
on most systems. Killing off the server is not guaranteed to notify
clients right away, so they have to wait until they timeout internally
on their ends first before any errors are reported by their OS. That
is simply the nature of how sockets work in general, because of the
way networks are designed, in particular in how they handle outages
and internal reconnects.
Gambit
 

Re:Client Disconnect from Server App that is not running - Sorry Remy - Another One

I apologise for my arrogance. You have always have known better seeing that
your are involved in Indy and you have also been of great help to me on all
my previous posts and I really appreciate it. And I look at other posts and
see that you always answer professionally and with great patience. Thank you
for that.
I am going to try out your suggestions and Post again if I run into any
trouble.
Thank you