Eviter TIME_WAIT

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.