This is not a question about how to do this, but a question about whether it's wrong what I'm doing. I've read that it's not possible to detect if a socket is closed unexpectedly (like killing the server/client process, pulling the network cable) while waiting for data (BeginReceive), without use of timers or regular sent messages, etc. But for quite a while I've been using the following setup to do this, and so far it has always worked perfectly.
public void OnReceive(IAsyncResult result)
var bytesReceived = this.Socket.EndReceive(result);
if (bytesReceived <= 0)
// normal disconnect
catch // SocketException
// abnormal disconnect
It's perfectly possible and OK to do this. The general idea is:
EndReceive returns anything other than zero, you have incoming data to process.
EndReceive returns zero, the remote host has closed its end of the connection. That means it can still receive data you send if it's programmed to do so, but cannot send any more of its own under any circumstances. Usually when this happens you will also close your end the connection thus completing an orderly shutdown, but that's not mandatory.
EndReceive throws, there has been an abnormal termination of the connection (process killed, network cable cut, power lost, etc).
A couple of points you have to pay attention to:
EndReceivecan never return less than zero (the test in your code is misleading).
BeginReceive; otherwise you will begin an infinite and meaningless ping-pong game between
EndReceive(it will show in your CPU usage). Your code already does this, so no need to change anything.