/etc/init.d/networking restart
Laissez-moi élaborer. Le protocole de contrôle de transmission (TCP) est conçu pour être un protocole de transmission de données bidirectionnel, ordonné et fiable entre deux points finaux (programmes). Dans ce contexte, le terme fiable signifie qu'il va retransmettre les paquets s'ils sont perdus en cours de route. TCP garantit la fiabilité en renvoyant des paquets d'accusé de réception (ACK) pour un seul paquet ou une plage de paquets reçus du pair.
Cela s'applique également aux signaux de contrôle tels que la demande/réponse de terminaison. RFC 793 définit l'état TIME-WAIT comme suit:
TIME-WAIT - représente l'attente du temps suffisant pour être certain que le TCP distant a reçu l'accusé de réception de sa demande de terminaison de connexion.
Consultez le schéma d'état TCP suivant:
TCP est un protocole de communication bidirectionnel, donc lorsque la connexion est établie, il n'y a pas de différence entre le client et le serveur. De plus, l'un ou l'autre peut décider de terminer la connexion, et les deux pairs doivent être d'accord pour la fermer complètement.
Appelons le premier à terminer la connexion comme le fermeur actif, et l'autre pair le fermeur passif. Lorsque le fermeur actif envoie FIN, l'état passe à FIN-WAIT-1. Ensuite, il reçoit un ACK pour le FIN envoyé et l'état passe à FIN-WAIT-2. Une fois qu'il reçoit également FIN du fermeur passif, le fermeur actif envoie l'ACK au FIN et l'état passe à TIME-WAIT. Dans le cas où le fermeur passif n'a pas reçu l'ACK pour le deuxième FIN, il retransmettra le paquet FIN.
RFC 793 fixe le TIMEOUT à deux fois la durée de vie maximale du segment, soit 2MSL. Puisque MSL, le temps maximum qu'un paquet peut errer sur Internet, est de 2 minutes, 2MSL équivaut à 4 minutes. Comme il n'y a pas d'ACK à un ACK, le fermeur actif ne peut rien faire d'autre que d'attendre 4 minutes s'il respecte correctement le protocole TCP/IP, au cas où le destinataire passif n'aurait pas reçu l'ACK pour son FIN (théoriquement).
En réalité, les paquets manquants sont probablement rares, et très rares s'ils se produisent tous à l'intérieur du LAN ou à l'intérieur d'une seule machine.
Pour répondre à la question littéralement, Comment fermer de force un socket en TIME_WAIT?, je vais quand même rester fidèle à ma réponse originale:
/etc/init.d/networking restart
En pratique, je le programmerais pour qu'il ignore l'état TIME-WAIT en utilisant l'option SO_REUSEADDR comme mentionné par WMR. Que fait exactement SO_REUSEADDR?
Cette option de socket indique au noyau que même si ce port est occupé (en
état TIME_WAIT), continuez et réutilisez-le quand même. Si c'est occupé, mais avec un autre état, vous obtiendrez toujours une erreur d'adresse déjà utilisée. C'est utile si votre serveur a été arrêté, et ensuite redémarré tout de suite alors que des sockets sont toujours actifs sur son port. Vous devez être conscient que si des données inattendues arrivent, cela peut confondre votre serveur, mais bien que cela soit possible, cela n'est pas probable.
1 votes
Si vous êtes ici en raison de "trop de
TIME_WAIT
sur le serveur", il suffit de passer les trois premières réponses qui évitent la question au lieu d'y répondre.0 votes
J'ai accepté ce qui était la 4e réponse, elle devrait donc être en haut maintenant
0 votes
Lien croisé : question associée sur Stack Overflow : c - Error: Address already in use while binding socket with address but the port number is shown free by
netstat
- Stack Overflow