2012-04-19 28 views
7

Mi aplicación C# .NET hace actualmente los siguientes (entre otras cosas):zócalo no se cierra después de la aplicación se cierra si un proceso iniciado está abierto

  1. Crea un hilo que establece una conexión con un puerto específico y espera una instrucción.
  2. El mensaje entra, el hilo del socket lee el mensaje y genera un evento.
  3. Un controlador de eventos llama a las funciones necesarias para analizar el mensaje y realiza la acción necesaria, por ejemplo, iniciar una aplicación.
  4. La "aplicación" externa especificada se inicia de forma asíncrona.

Cuando mis reinicia la aplicación, pero la aplicación externa no se cierra, la toma no parece siempre muy unidos. Luego, cuando trato de iniciar la comunicación en ese puerto de nuevo, aparece un error. Sin embargo, tan pronto como cierro la aplicación externa, puedo abrir un socket en ese puerto.

Parece que mi programa no se cierra correctamente. Debería estar matando el zócalo cuando sale, sin embargo, cuando el proceso externo se está ejecutando ese zócalo nunca se cierra.

¿Alguna idea?

+0

¿Está desechando el zócalo? –

+0

¿Cómo está ejecutando el proceso externo? Por favor publique un código – zmbq

+0

@ M.Babcock Sí, estoy cerrando el socket y he verificado que el código se está ejecutando cuando se cierra la IU. Estoy usando un TcpClient y un TcpListener. El cliente está siendo "cerrado" y el oyente está siendo "detenido". Sin embargo, esto no parece liberar el puerto. – JSideris

Respuesta

13

Esto es solo una puñalada porque he visto cómo está iniciando el proceso externo. Si va a crear un objeto de proceso, mi conjetura es que no se está configurando:

ProcessStartInfo.UseShellExecute = true; 

Si UseShellExecute se establece en false, el proceso hijo heredará socket abierto se encarga del proceso padre. Esto mantendrá su socket abierto incluso si la aplicación principal está cerrada.

+0

Justo en el dinero. UseShellExecute se estaba configurando en falso para poder redirigir/eliminar las secuencias de entrada. Después de deshacerse de la redirección y establecer UseShellExecute en true, los puertos se liberan. ¡Gracias! – JSideris

+0

Me alegro de poder ayudar. Nos encontramos con este problema hace un mes. Recibíamos un error de socket después del error de socket incluso cuando los objetos se estaban desechando correctamente. Afortunadamente, uno de los muchachos lo encontró enterrado en algún lugar de MSDN. – Josh

+0

igual que [http://stackoverflow.com/a/24677139/4123833](http://stackoverflow.com/a/24677139/4123833), contiene otras dos soluciones/opciones en eso. – aspark

0

Usted puede ser capaz de resolver esto con el uso de palabras clave

using (Socket socket = new Socket()) { 
//The code 
} 

¿Utiliza la otra aplicación de la toma en absoluto?

+0

La otra aplicación no usa el socket. Lo estoy probando con una aplicación aleatoria en mi sistema ... por ejemplo, Firefox. – JSideris

+0

Solo para estar seguro: si no abre una aplicación externa, ¿su problema luego libera el socket? – Anders

+0

Sí, el socket se libera cuando la aplicación externa no se inicia. – JSideris

1

De lo que encontré here mi sospecha podría ser confirmada que este es un caso del nuevo proceso heredando identificadores del padre, causando su problema.

Parece que puede simplemente copiar/pegar el código de ese enlace para hacer una llamada directa a la API CreateProcess de Windows con el indicador configurado para no heredar identificadores.

Otra idea por separado es escribir un programa iniciador intermedio que toma la información de línea de comando y luego se inicia y luego se cierra. Esta indirección adicional podría llevarte a donde necesitas estar con muy poco esfuerzo.

+0

Parece que 'cmd' sería una buena opción para un lanzador intermedio de este tipo con muy poco esfuerzo. –

0

Lo primero es echar un vistazo al estado del zócalo cuando se cierra la aplicación. El socket podría estar en el estado TIME_WAIT, lo que significa que esperará un tiempo para asegurarse de que no se recibirán otros mensajes. Puede leer sobre esto aquí: http://www.isi.edu/touch/pubs/infocomm99/infocomm99-web/ Ahora se generará el estado TIME_WAIT en el socket según cuál de ellos inició el procedimiento de terminación de la conexión. Entonces, si por algún motivo su socket realiza la acción cercana en el sitio del servidor, en el sitio del servidor (en el puerto del servidor) el socket cambiará el estado a TIME_WAIT, por lo que si reinicia su aplicación de servidor durante el socket está en TIME_WAIT a El nuevo socket no se unirá al puerto de escucha, creo que este es el problema que conociste.

Cuestiones relacionadas