Can it happen that a socket client closes connection and the server doesen’t know this ?
I received several error on the event BeginReceive() in C#.
How to check if the client is still alive and in which places of my program would be better to place this checks ?
Can it happen that a socket client closes connection and the server doesen’t know
Share
There are several kinds of “closed connections” when programming with sockets. (I’ll use the BSD-derived system call names for the socket operations, I hope they kept similar names through the changes to C#.)
The client program closes the socket using
shutdown()orclose(). When this happens, TCP will send aFINpacket to your server. This will show up as a closed socket in your server when you try to read beyond the last byte of data sent by the client. The nextread()will probably throw an exception or error condition. (Varies by environment.) This condition is usually available to polling-style interfaces (such asselect(2)orpoll(2)) so your standard event loop handler can discover client quits and handle them.The client program can unexpectedly quit. In this case, the client’s TCP implementation will probably send
FINpackets, but it might not be in an “expected” place in your application’s input parser. Be prepared to handle zero-byte reads orEOFreads that indicate a premature application termination.The client host can unexpectedly die. In this case, the client’s TCP implementation won’t be able to send a
FINpacket to your server and you will not receive any notification at all that the client connection has terminated. You can enable the TCPSO_KEEPALIVEsocket option, but at least Linux defaults to a system-wide time of two hours of inactivity before sending the keepalive probes.If the system comes back up ‘quickly’, your application will receive either TCP
RSTpackets in response or silence if a stateful firewall is configured toDROPpackets that don’t match allowed or initiated traffic streams. TheRSTcase can be detected similar to theFINpackets. The silence of dropped packets can only be detected with an application-level keepalive packet scheme.So it’s best to build in an application-level keepalive ping packet of some sort on a time frame that is acceptable to you. (For example, IRC uses
PINGandPONGpackets to ensure clients are still connected to servers — the time between checks is configurable by network administrators.)How long you’ll go between pings and how many failed ping packets to accept depends heavily upon your application — you might be willing to allow twenty minutes to elapse before noticing and removing a disconnected client, or you might want to notice and remove a disconnected client after only twenty seconds. How long depends upon the working environment (20 seconds wouldn’t work for a Mars rover but might be ten times too long for a LAN-connected First-Person-Shooter video game) and network bandwidth available for “administrative overhead” like this.