I have trouble with detecting client disconnect from host. Currently my code looks like this:
Task.Run(() => {
// Create server
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) {
ReceiveTimeout = -1,
};
server.Bind(new IPEndPoint(IPAddress.Any, port));
server.Listen(-1);
// Start listening
while (true) {
Socket socket = server.Accept();
new Thread(() => {
try {
Process(socket);
} catch (Exception ex) {
Trace.WriteLine("Socket connection processing error: " + ex.Message);
}
}).Start();
}
});
// Host client process
void Process(Socket socket) {
byte[] response;
int received;
var ip = IPAddress.Parse(((IPEndPoint) socket.RemoteEndPoint).Address.ToString());
Events.OnNodeConnected(ip);
while (true) {
// Rceive data
response = new byte[socket.ReceiveBufferSize];
received = socket.Receive(response);
// Check connection
if (!socket.IsConnected()) {
socket.Close();
Events.OnNodeDisconnected(ip);
return;
}
try {
// Decode recieved data
List < byte > respBytesList = new List < byte > (response);
And the IsConnected() extension:
public static class SocketExtensions {
public static bool IsConnected(this Socket socket) {
try {
return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
} catch (SocketException) {
return false;
}
}
}
Works when I close the application, but not when I turn off the network card. I’m testing this on Debian virtual machines running on VirtualBox. Is there any way to detect disconnection in this case?
2
Answers
I have similary problem, when i want to know if my network interface is known or not
i am using this piece of code to check the different network interfaces:
file NetworkMonitor.cs
you could use these files like this for example:
you trap the list of network devices, so you could check if your prefered network device is known or unknown
If you want you could measure the speed of download and/or upload if you want..
following the version of framework you have to included in the exe.config file this piece of code :(to avoid the error -> InvalidOperation : Instance ‘XXX’ does not exist in the specified Category)
Turning off the network card is actually not a disconnect. If the network card is turned on again the existing connection can continue (providing the interface has still the same IP address) – this is not unusual for example when suspending a laptop and resuming it later.
With TCP a real disconnect is only an explicit disconnect (FIN gets send) which is done when explicitly closing the socket or which gets implicitly done by the OS kernel on application exit or when the application crashes.
What you instead ask for is not an explicit disconnect but to detect if the peer is currently not reachable, like when the line is (temporarily) disconnected or the system has crashed. This can be done by having some kind of heartbeat either at the application level or at the TCP level. The latter is called TCP keep alive and works by sending empty TCP packets and check if an ACK is sent back. See here for an example on how to use this.