I don't understand why would you use
client.Connected
at all. The problem looks very simple to me; I face such disconnections everywhere and never had problems with it.
The idea is: you should have some main cycle where you exchange data with all clients. Inside that cycle, everything should be done under the try-catch loop. If you, for an experiment, at first step, catch all the exception and some client disconnects, you will see what exceptions are thrown and handle them specifically in your next version of the code. From exception information, you will see what client has been disconnected (a client is represented either as the instance of
Socket
representing remote socket, or an instance of
TcpClient
). When you determine that, remove the client from the client collection and continue the loop with other clients, or do whatever is needed. Naturally, something like that should be done on the client side.
Note that there is one special case of disconnection, which is an issue. If you disconnect the application (just terminated it), the situation is detected immediately and the exception is thrown. The issue is when you physically break the network cable, not changing anything. This situation is only detected after a relatively long timeout. (You can define your timeout values, but its reasonable to have fairly long time-outs. The bright side is that you can re-connect the cable, and then the communication will continue.) Basically, such wait is always involved. You can experiment with it on a LAN, for example. The work-around would be checking up physical connection with a separate channel and short timeout values (pinging is one of such option), but this strategy would be redundant/wasteful and hardly makes much sense.
I assume that you work with all clients in the same thread (or even work with only one client). However, main issue here is threading. You really need to have at least two separate communication threads on the server side: one thread accepts the new client, another thread reading/writing from/to the network stream. Of course, you need to use appropriate locking for the shared data (such as the collection of connected client or something else related to the clients, such as client-related data).
Please see also my past answers:
an amateur question in socket programming[
^],
Multple clients from same port Number[
^].
Note my paragraph about
graceful disconnection: I try to explain why it hardly makes sense: the application should be ready for all kind of disconnections anyway.
—SA