2010-10-16 16 views
8

Tengo un red5 server (JAVA) ejecutándose en mi servidor Linux.Linux: ¿Cómo matar programas que usan el puerto 1935?

A veces, el servidor se apaga. Cuando trato de reiniciar recibí un error:

"Error de encuadernación, este puerto está en uso aleray".

así que trato de matar al servidor con killall -9 java y tratar de reiniciar el servidor: mismo error.

Tengo que esperar un tiempo (unos 2-3 minutos) y reiniciarlo de nuevo: eso funciona.

Solo necesito saber por qué cuando elimino el proceso todavía tengo que esperar 2-3 minutos antes de que el puerto 1935 sea gratuito y pueda ejecutar el servidor nuevamente.

¿Hay una manera de matar este proceso inmediatamente y liberar el puerto?

+1

no lo hago cree las respuestas que culpan a SIGKILL por una limpieza fallida del puerto. El sistema operativo sabe perfectamente que el proceso se ha ido y renuncia a sus recursos de la manera estándar. La forma estándar para un puerto de escucha TCP cerrado es que no estará disponible durante un tiempo para evitar que se conecte al servidor incorrecto. Esto se puede evitar más fácilmente al usar SO_REUSEADDR como se menciona en la respuesta de Justin. –

Respuesta

16

Si está seguro de edad instancia de su servidor tiene el puerto, basta con ejecutar jps, encontrar su PID servidor en la lista y ejecutar kill -9 my_pid

Para el proceso no Java genérico, lsof -i :1935 por lo general funciona para mí. De nuevo, toma pid y mata este proceso.

5

Si es posible, se debe utilizar la opción de conector SO_REUSEADDR cuando el programa establece su zócalo. De esta forma, puede reutilizar inmediatamente el socket cuando se reinicie el programa, en lugar de tener que esperar 2-3 minutos.

Consulte el javadoc setReuseAddress para obtener más información. En particular:

When a TCP connection is closed the connection may remain in a timeout state for a period of time after the connection is closed (typically known as the TIME_WAIT state or 2MSL wait state). For applications using a well known socket address or port it may not be possible to bind a socket to the required SocketAddress if there is a connection in the timeout state involving the socket address or port.

Enabling SO_REUSEADDR prior to binding the socket using bind(SocketAddress) allows the socket to be bound even though a previous connection is in a timeout state.

+0

Puede hacerlo en Java llamando a setReuseAddress http://download.oracle.com/javase/1.4.2/docs/api/java/net/ServerSocket.html –

+0

Parece que los dos estábamos pensando lo mismo - vea mi edits :) –

9

El problema es la en la matanza.

Si mata un proceso con SIGKILL (-9), el proceso finaliza inmediatamente. Entonces, el puerto permanece asignado hasta (un minuto después) el O.S. nota el problema Pruebe SIGHUP y SIGINT (en el orden) antes de SIGKILL.

En cualquier caso, use netstat -a -t -p para verificar qué proceso ha adquirido el puerto.

1

kill -9 no se debe usar de manera predeterminada. El proceso no puede limpiar cosas internas. para matar a los PID de la aplicación utilizando por el puerto exemple 8000:

kill $(netstat -nptl | awk '/:8000/{gsub("/.*", ""); print $7}') 
+0

kill: uso: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... o kill -l [sigspec] – yarek

+0

parece que hay un error con este comando: kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | trabajospec ... o matar -l [sigspec] – yarek

1

Ésta es una oneliner útil:

kill $(fuser 1935/tcp) 
7

procesar inmediatamente la terminación y el puerto de liberación:

fuser -k 1935/tcp 
Cuestiones relacionadas