He escrito un pequeño programa que interactúa con un servidor en un puerto específico. El programa funciona bien, pero:
Una vez que el programa terminó inesperadamente, y desde entonces esa conexión de socket se muestra en CLOSE_WAIT
estado. Si trato de ejecutar un programa, se cuelga y tengo que forzarlo a cerrar, lo que acumula aún más CLOSE_WAIT
conexiones de socket.
¿Hay alguna forma de limpiar estas conexiones?
Respuestas:
CLOSE_WAIT
significa que su programa aún se está ejecutando y no ha cerrado el socket (y el kernel está esperando que lo haga). Agregue-p
paranetstat
obtener el pid y luego elimínelo con más fuerza (conSIGKILL
si es necesario). Eso debería deshacerse de susCLOSE_WAIT
enchufes. También puede usarps
para encontrar el pid.SO_REUSEADDR
es para servidores yTIME_WAIT
sockets, por lo que no se aplica aquí.fuente
Como lo describe Crist Clark .
fuente
close()
oclosesocket()
, según la plataforma que esté utilizando.También tengo el mismo problema con un servidor Tomcat más reciente (7.0.40). No responde una vez durante un par de días.
Para ver las conexiones abiertas, puede usar:
Como se mencionó en esta publicación , puede usar
/proc/sys/net/ipv4/tcp_keepalive_time
para ver los valores. El valor parece estar en segundos y el valor predeterminado es 7200 (es decir, 2 horas).Para cambiarlos, debe editarlos
/etc/sysctl.conf
.fuente
Aunque demasiadas conexiones CLOSE_WAIT significan que hay algo mal en su código en la primera y esto no se acepta como una buena práctica.
Es posible que desee consultar: https://github.com/rghose/kill-close-wait-connections
Lo que hace este script es enviar el ACK que estaba esperando la conexión.
Esto es lo que funcionó para mí.
fuente
Cabe mencionar que la
Socket
instancia tanto en el cliente como en el servidor debe invocar explícitamenteclose()
. Si solo uno de los extremos invocaclose()
entonces, el conector permanecerá en estado CLOSE_WAIT.fuente
Puede cerrar sockets a la fuerza con el
ss
comando; elss
comando es una herramienta que se usa para volcar estadísticas de sockets y muestra información de manera similar (aunque más simple y rápida) a netstat.Para matar cualquier socket en el estado CLOSE_WAIT, ejecute esto (como root)
fuente
También vale la pena señalar que si su programa genera un nuevo proceso, ese proceso puede heredar todos sus identificadores abiertos. Incluso después de que se cierre su propio programa, esos identificadores heredados pueden seguir vivos a través del proceso hijo huérfano. Y no necesariamente aparecen de la misma manera en netstat. Pero de todos modos, el socket permanecerá en CLOSE_WAIT mientras este proceso hijo esté vivo.
Tuve un caso en el que estaba ejecutando ADB. El propio ADB genera un proceso de servidor si aún no se está ejecutando. Esto heredó todos mis identificadores inicialmente, pero no apareció como propietario de ninguno de ellos cuando estaba investigando (lo mismo era cierto para macOS y Windows, no estoy seguro de Linux).
fuente