Estoy desarrollando un servidor en C# que puede aceptar solo un cliente y necesito saber cuándo este cliente está desconectado para poder aceptar otras solicitudes de conexión.¿La mejor práctica para detectar una desconexión del cliente en .NET?
Estoy usando un primer Socket que escucha continuamente la solicitud de conexión con Socket.BeginAccept
y acepta o rechaza clientes. Cuando se acepta un cliente, se utiliza el nuevo Socket que se devuelve por Socket.EndAccept
para la comunicación entre el cliente y el servidor. Luego, el servidor espera los comandos del cliente con Socket.Begin/EndReceive
y envía respuestas. El servidor utiliza un protocolo similar a Telnet, lo que significa que cada comando y cada línea de respuesta debe finalizar con \r\n
.
Para detectar si el cliente ha sido desconectado, he instalado un temporizador que envía cada 500 ms un mensaje vacío ("\r\n
") al cliente. Si el cliente está desconectado, el Socket lanza una excepción. Esta excepción es capturada por el servidor que cierra la sesión actual y acepta una nueva conexión. Esta solución es robusta pero implica tráfico innecesario en la red y debe ser manejada correctamente por el cliente, que debe filtrar los mensajes falsos antes de obtener una respuesta real.
He intentado enviar un búfer vacío (Socket.Send(new byte[1], 0, 0)
), pero parece que no funciona en la dirección server-> client.
Otra solución podría ser manejar el caso en el que Socket.EndReceive
devuelve 0 bytes. Funciona bien para el caso de una desconexión que ocurre durante el tiempo "inactivo". Pero si el cliente se desconecta durante la transferencia de un mensaje, el servidor no siempre lo ve y espera indefinidamente.
Ya he visto varios hilos y preguntas sobre este problema, pero nunca he visto una buena solución.
Entonces mi pregunta es: ¿cuál es la mejor manera de detectar una desconexión en .Net?
OK, he agregado que permite KeepAlive para mi zócalo. Pero, ¿qué se supone que debo esperar ahora? No sucede nada cuando el cliente rompe la conexión ... Esperaba recibir una excepción en alguna parte ... ¿Debo leer o escribir algo periódicamente? – cedrou
¿Pensé que estabas usando Begin/EndReceive? Si es así, el BeginReceive debe ejecutar la devolución de llamada y cuando llame a EndReceive para obtener el resultado, se debe hacer una excepción, eso o un final de la transmisión de 0 byte. –
OK, tengo una excepción ahora ... Gracias – cedrou