简体   繁体   中英

Can it happen that a socket client closes connection and the server doesen't know this?

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 ?

Assuming you're talking about a protocol layered on top of TCP, yes it can happen. TCP doesn't require any packets to be sent to keep a connection alive. So if the packets that close the connection don't get through to the server, the server may think the client is still there, even long after the client has closed the connection.

Because this is a well-known property of TCP, every protocol layered on top of TCP has to take this into account. So if you simply follow the protocol, you won't have a problem.

The exceptions are if the protocol is very badly designed or if you are designing the protocol. If you are designing the protocol, you have a lot of choices. For example, you can specify that one end must send some kind of message at least every 10 minutes. And you can specify that the other end should close the connection if it doesn't receive any message for 20 minutes.

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() or close() . When this happens, TCP will send a FIN packet 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 next read() will probably throw an exception or error condition. (Varies by environment.) This condition is usually available to polling-style interfaces (such as select(2) or poll(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 FIN packets, but it might not be in an "expected" place in your application's input parser. Be prepared to handle zero-byte reads or EOF reads 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 FIN packet to your server and you will not receive any notification at all that the client connection has terminated. You can enable the TCP SO_KEEPALIVE socket 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 RST packets in response or silence if a stateful firewall is configured to DROP packets that don't match allowed or initiated traffic streams. The RST case can be detected similar to the FIN packets. 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 PING and PONG packets 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM