2008-10-03 10 views
9

Estoy buscando una forma de hacer un control de mantener vivo en .NET. El escenario es para UDP y TCP.¿Cuál es la mejor manera de mantener vivo el control de socket en .NET?

Actualmente en TCP, lo que hago es que un lado se conecta y cuando no hay datos para enviar envía un mantener vivo cada X segundos.

Quiero que el otro lado compruebe los datos, y si no se recibió en X segundos, para generar un evento más o menos.

Una forma en que traté de hacerlo fue hacer un bloqueo de recepción y configurar el RecieveTimeout del zócalo en X segundos. Pero el problema era que cada vez que pasaba el tiempo de espera, la recepción del zócalo arrojaba una excepción SocketExeception y el zócalo de este lado se cerraba, ¿es este el comportamiento correcto? ¿por qué el socket se cierra/muere después del tiempo de espera en lugar de simplemente continuar?

Una verificación de si hay datos y la suspensión no es aceptable (ya que podría estar retrasada en la recepción de datos mientras duermo).

Entonces, ¿cuál es la mejor manera de hacerlo, y por qué el método que describí del otro lado está fallando?

Respuesta

0

Dado que no puede usar la recepción de bloqueo (síncrono), tendrá que conformarse con el manejo asíncrono. Afortunadamente, es bastante fácil de hacer con .NET. Busque la descripción de BeginReceive() y EndReceive(). O mira esto article o this.

En cuanto al comportamiento de tiempo de espera no encontré una descripción concluyente de esto. Como no está documentado de otra manera, debes asumir que es el comportamiento previsto.

+1

Sí, se olvidó de mencionar las operaciones asincrónicas, pero lo que mi pregunta es ¿Alguien tiene experiencia con RecieveTimeout y por qué se produce un error en la forma anterior (porque entonces mi código sería aún más fácil a continuación, utilizando RecieveTimeout. –

1

De acuerdo con MSDN, una SocketException lanzada cuando ReceiveTimeout se excede en la llamada de recepción no cerrará el socket. Hay algo más sucediendo en tu código.

Compruebe los detalles de SocketException capturados, tal vez no sea un tiempo de espera después de todo. Quizás el otro lado de la conexión apague el enchufe.

Considere habilitar el seguimiento de red para diagnosticar el origen exacto de sus problemas: busque "Network Tracing" en MSDN (no se le puede proporcionar un enlace, ya que en este momento MSDN está inactivo).

+0

En realidad, el el otro lado todavía ve el zócalo como abierto (mientras que este lado no). Esta parte del código no es compleja, trataré de reproducirlo en un caso de prueba más pequeño. –

14

Si literalmente significa "KeepAlive", intente lo siguiente.

public static void SetTcpKeepAlive(Socket socket, uint keepaliveTime, uint keepaliveInterval) 
    { 
     /* the native structure 
     struct tcp_keepalive { 
     ULONG onoff; 
     ULONG keepalivetime; 
     ULONG keepaliveinterval; 
     }; 
     */ 

     // marshal the equivalent of the native structure into a byte array 
     uint dummy = 0; 
     byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3]; 
     BitConverter.GetBytes((uint)(keepaliveTime)).CopyTo(inOptionValues, 0); 
     BitConverter.GetBytes((uint)keepaliveTime).CopyTo(inOptionValues, Marshal.SizeOf(dummy)); 
     BitConverter.GetBytes((uint)keepaliveInterval).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2); 

     // write SIO_VALS to Socket IOControl 
     socket.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null); 
    } 
+2

Me pregunto si siquiera lees el pregunta :) por supuesto que no soy –

+8

Me divierte que le respondas a alguien que está tratando de ayudarte de esa manera. –

+1

Vale la pena aclarar que esta respuesta es la única en C# que le permite realizar keepalives de nivel TCP en lugar de hacerlo manualmente en el código (se configura y olvida) y le permite elegir el tiempo de espera (activando SocketOptionName.KeepAlive usando SetSocketOption utiliza un tiempo de espera de 2 horas, demasiado tiempo para la mayoría de las aplicaciones). Más información aquí: http://blog.stephencleary.com/2009/05/detection-of-half-open-dropped.html – Derek

Cuestiones relacionadas