2010-05-12 13 views
11

Estoy tratando de detener un Oyente TCP cuando mi programa está saliendo. No me importan los datos que estén actualmente activos en el socket o cualquiera de los sockets de clientes activos.TcpListener El socket sigue activo después de las salidas del programa

La toma de limpiar el código es esencialmente:

try 
{ 
    myServer.Server.Shutdown(SocketShutdown.Both) 
} 
catch (Exception ex) 
{ 
    LogException(ex) 
} 
myServer.Server.Close(0) 
myServer.Stop() 

miServidor es un TCPListener

En algunas ocasiones, apagado se produce una excepción

System.Net.Sockets.SocketException: No se permitió una solicitud para enviar o recibir datos porque el socket no está conectado y (cuando se envía en un socket de datagrama usando una llamada a sendto) no se suministró ninguna dirección en Sys tem.Net.Sockets.Socket.Shutdown (SocketShutdown cómo)

Edición 2010-mayo-14

Tras realizar investigaciones adicionales, la excepción puede ser lanzada y el zócalo se puede cerrar correctamente.

A veces, incluso después de que la aplicación sale de netstat muestra que el zócalo aún está en el estado de ESCUCHA.

No he podido crear un escenario de reproducción definitiva, sucede en momentos aparentemente aleatorios.

Los zócalos de cliente se limpian de forma independiente.

¿Tiene alguna sugerencia que me ayude a hacer que este socket muera?

+0

Las tomas de corriente C# se están comportando bastante raras en mi opinión. O tal vez solo son ventanas.Tengo un problema similar (aún no resuelto), quizás las respuestas te ayuden, aunque nuestros problemas son un poco diferentes: http://stackoverflow.com/questions/2821520/how-can-i-unbind-a-socket- in-c – IVlad

+0

Los problemas son muy similares. El socket permanece en el estado LISTENING, no cambia a TIME_WAIT. Relanzar la aplicación provoca el error "Solo un uso de cada dirección de socket ...". – lnical

+0

Bueno, solo estaba siendo estúpido, obtuve la solución ahora. El problema es que me funcionó después de reiniciar el programa, no sin reiniciarlo. ¿Estás usando hilos en tu programa? – IVlad

Respuesta

1

Intente llamar de parada antes del cierre ...

0

Después de que sus salidas de aplicaciones, el conector no puede estar en un estado de escucha. Sin embargo, puede estar en un estado de espera; esto es perfectamente normal.

+0

La aplicación ya no aparece en el Administrador de tareas. El PID asociado con el socket no está relacionado con ningún proceso en el administrador de tareas. Estado de conexión según netstat ESCUCHA tres horas después de que la aplicación haya salido. – lnical

+0

Tengo el programa salido y el socket actualmente escuchando en este momento. Si hay más información que le gustaría, hágamelo saber. – lnical

+1

¿Podría verificar utilizando [Process Explorer] (http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx) y [TCPView] (http://technet.microsoft.com/en-us/sysinternals /bb897437.aspx)? TCPView debería dar el mismo resultado que netstat, pero Process Explorer es más exhaustivo que Task Manager. –

3

Use un bloque finally para llamar a Close() en el caso de una excepción:

try 
{ 
    myServer.Server.Shutdown(SocketShutdown.Both); 
} 
catch (Exception ex) 
{ 
    LogException(ex); 
} 
finally 
{ 
    myServer.Server.Close(0); 
    myServer.Stop(); 
} 

También tengo curiosidad si se requiere la manipulación de la cavidad subyacente a causa de alguna especificación que usted no ha mencionado? TCPListener/Client está diseñado para evitar que se preocupe por los mecanismos de comunicación en la mayoría de los casos.

Además, si esto no ayuda, ¿qué código de error devuelve SocketException?

+0

El socket se ha apagado debido a este socket abierto después de la salida del programa. En algunos casos (no todos, y no totalmente reproducibles) el socket permanece abierto en estado de escucha. En el código de producción, los comandos cerrar y detener se envuelven en otro constructo try-catch-finally con más logging. Esos comandos no arrojan una excepción. A juzgar por el código de error creo que el código de error es WSAENOTCONN 10057. Sobre la investigación adicional, en otras ocasiones se lanza el error de apagado y la toma se cierra normalmente. Editaré la pregunta principal para agregar esa información. Gracias. – lnical

+0

Pensando en posibles soluciones me pregunto si el cliente es la causa. El Dispose del socket es una respuesta al cierre del cliente. Entonces, el estado huérfano del socket podría ser un síntoma de que un cliente no se desconecta correctamente. ¿La conexión y la desconexión del cliente están diseñadas de manera relativamente atómica? También creo que el rastreo podría ayudar a revelar el problema. Eche un vistazo a este enlace para configurarlo, si aún no lo ha hecho: http://2.ly/3K2 Escribo las instrucciones pero no me quedan suficientes caracteres. Se requerirá cierto cribado, pero el rastreo debería revelar dónde se produce la interrupción de la comunicación. – Sorax

0

tenían un problema similar: - TcpListener la espera de los clientes se conecten - Disponer en una estrecha

tenido el mismo problema (win7, win2k).

Una solución que funciona (? Hasta ahora) para mí fue cerrar cada una de las conexiones con el cliente al deshacerse del oyente. Parece que si el programa existe mientras todavía hay conexiones activas VS a un cliente, esa conexión puede permanecer después de que el programa se apaga.

Cuestiones relacionadas