104 votes

Comment supprimer une connexion de socket CLOSE_WAIT ?

J'ai écrit un petit programme qui interagit avec un serveur sur un port spécifique. Le programme fonctionne bien, mais :

Une fois que le programme s'est terminé de manière inattendue, et depuis cette connexion de socket est affichée en CLOSE_WAIT l'état. Si j'essaie d'exécuter un programme, il se bloque et je dois le forcer à se fermer, ce qui accumule encore plus de travail. plus CLOSE_WAIT les connexions de douilles.

Y a-t-il un moyen de rincer ces connexions ?

91voto

derobert Points 26258

CLOSE_WAIT signifie que votre programme est toujours en cours d'exécution et qu'il n'a pas fermé le socket (et le noyau attend qu'il le fasse). Ajouter -p a netstat pour obtenir le pid, et ensuite le tuer plus vigoureusement (avec SIGKILL si nécessaire). Cela devrait vous débarrasser de votre CLOSE_WAIT les prises de courant. Vous pouvez également utiliser ps pour trouver le pid.

SO_REUSEADDR est pour les serveurs et TIME_WAIT sockets, donc ne s'applique pas ici.

43voto

user2618402 Points 21

Comme décrit par Crist Clark .

CLOSE_WAIT signifie que l'extrémité locale de la connexion a reçu un signal FIN de l'autre extrémité, mais le système d'exploitation attend que le programme de l'extrémité locale l'extrémité locale ferme effectivement sa connexion.

Le problème est que votre programme fonctionnant sur la machine locale ne ferme pas ferme pas le socket. Ce n'est pas un problème de réglage du TCP. Une connexion peut (et c'est bien normal) rester en CLOSE_WAIT pour toujours pendant que le programme maintient la connexion ouverte.

Une fois que le programme local ferme le socket, le système d'exploitation peut envoyer le FIN à l'extrémité distante. FIN à l'extrémité distante, ce qui vous fait passer à LAST_ACK pendant que vous attendez l'ACK de la FIN. Une fois qu'il est reçu, la connexion est terminée et est supprimée de la table de connexion (si votre extrémité est en CLOSE_WAIT, vous n'avez pas besoin d'attendre). faites no se retrouvent dans l'état TIME_WAIT).

25voto

Mustapha Hadid Points 144

Vous pouvez forcer la fermeture des sockets avec ss la commande ss est un outil utilisé pour vider les statistiques des sockets et affiche des informations de manière similaire (bien que plus simple et plus rapide) à netstat.

Pour tuer toute socket dans l'état CLOSE_WAIT, exécutez ceci (en tant que Root)

$ ss --tcp state CLOSE-WAIT --kill

Vous pouvez également filtrer votre action

$ ss --tcp state CLOSE-WAIT '( dport = 22 or dst 1.1.1.1 )' --kill

9voto

mirage Points 523

Même si trop de connexions CLOSE_WAIT signifie que quelque chose ne va pas dans votre code et que ce n'est pas une bonne pratique.

Vous pourriez vouloir vérifier : https://github.com/rghose/kill-close-wait-connections

Ce que fait ce script est d'envoyer l'ACK que la connexion attendait.

C'est ce qui a marché pour moi.

8voto

Amil Waduwawara Points 748

J'ai également le même problème avec un serveur Tomcat très récent (7.0.40). Il ne répond plus une fois pendant quelques jours.

Pour voir les connexions ouvertes, vous pouvez utiliser :

sudo netstat -tonp | grep jsvc | grep --regexp="127.0.0.1:443" --regexp="127.0.0.1:80" | grep CLOSE_WAIT

Comme mentionné dans ce poste vous pouvez utiliser /proc/sys/net/ipv4/tcp_keepalive_time pour visualiser les valeurs. La valeur semble être en secondes et la valeur par défaut est de 7200 (c'est-à-dire 2 heures).

Pour les modifier, vous devez éditer /etc/sysctl.conf .

Open/create `/etc/sysctl.conf`
Add `net.ipv4.tcp_keepalive_time = 120` and save the file
Invoke `sysctl -p /etc/sysctl.conf`
Verify using `cat /proc/sys/net/ipv4/tcp_keepalive_time`

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X