J’essaie d’éviter TIME_WAIT chez un client. Je me connecte et puis définir O_NONBLOCK et SO_REUSEADDR. J’appelle read jusqu’à ce qu’il renvoie 0. Lorsque read renvoie 0, le code d’erreur est aussi 0. Je l’ai interprété comme un signe indiquant que le serveur a fermé la connexion. Cependant, si j’appelle close, le socket est défini sur TIME_WAIT, comme confirmé par netstat.
Étant donné que je me connecte plusieurs fois au même hôte / port, je finis par voir des erreurs “Address in use” (voir ” http://www.harvard.edu/~fine/Tech/addrinuse.html” ).
Devrais-je téléphoner à proximité après le retour à la lecture 0? Si je ne le fais pas, le descripteur de fichier sera-t-il publié?
Le côté qui a initié la fermeture de la connexion est celui qui se retrouve dans l’état TIME_WAIT
. read()
renvoyer 0 est supposé indiquer que le serveur a fermé le socket en premier, donc oui – cela devrait signifier que TIME_WAIT
se termine côté serveur et que le client passe par LAST_ACK
.
En fin de journée, vous ne pouvez pas éviter un état TIME_WAIT
. Même si vous réussissez à le déplacer du côté serveur au côté serveur, vous ne pouvez toujours pas réutiliser ce tuple (server host, server port, client host, client port)
jusqu’à ce que TIME_WAIT
soit terminé (quel que soit le côté sur lequel il se trouve) ).
Étant donné que trois parties de ce tuple sont corrigées dans votre scénario ( server host
server port
, client host
), vous ne disposez réellement que des options suivantes:
Essayez de rendre plus de ports clients disponibles. Certains systèmes d’exploitation n’utilisent par défaut qu’une petite partie des ports disponibles pour les “ports éphémères” (je ne suis pas sûr à propos d’OSX à cet égard). Si c’est le cas, voyez si vous pouvez modifier la plage avec un réglage de configuration dans le système d’exploitation, ou demander à l’application de rechercher un port opérationnel avec bind()
/ connect()
dans une boucle jusqu’à ce que la connexion fonctionne.
Développez le nombre de valeurs d’ client host
disponibles en utilisant plusieurs adresses IP sur votre client. Vous devrez cependant avoir l’application bind()
avec l’une de ces adresses IP spécifiquement.
Développez le nombre de valeurs de server port
server host
/ server port
disponibles, en utilisant plusieurs ports et / ou adresses IP sur le serveur. Le client devra en choisir un auquel se connecter (round robin, random, etc.).
Probablement la meilleure option, si cela est faisable: refactoriser votre protocole afin que les connexions terminées ne soient pas fermées, mais passez à l’état “inactif” afin qu’elles puissent être réutilisées ultérieurement, au lieu d’ouvrir une nouvelle connexion (comme HTTP). restr en vie).
Plus tard sur la même page, ils mentionnent SO_REUSEADDR. C’est ce dont tu as besoin. Vous voulez absolument fermer le descripteur de fichier lu quand il renvoie zéro.
La définition de SO_REUSEADDR du côté client n’aide pas le côté serveur si elle ne définit pas également SO_REUSEADDR.