Je sais qu'il y a pas mal de questions SE à ce sujet, et je crois que j'en ai lu autant qu'il le faut avant d'en arriver là.
Par "côté serveur TIME_WAIT
", j'entends l'état d'une paire de sockets côté serveur dont la fermeture () a été déclenchée côté serveur.
Je vois souvent ces déclarations qui me semblent contradictoires:
- Côté serveur
TIME_WAIT
est inoffensif - Vous devez concevoir vos applications réseau pour que les clients lancent close (), donc le client doit
TIME_WAIT
La raison pour laquelle je trouve cela contradictoire est que TIME_WAIT
le client peut être un problème - le client peut manquer de ports disponibles, donc essentiellement ce qui précède recommande de déplacer la charge du TIME_WAIT
côté client où il peut être problématique, du côté serveur où ce n'est pas un problème.
Le côté client TIME_WAIT
n'est bien sûr qu'un problème pour un nombre limité de cas d'utilisation. La plupart des solutions client-serveur impliqueraient un serveur et de nombreux clients, les clients ne traitent généralement pas avec un volume de connexions suffisamment élevé pour que ce soit un problème, et même s'ils le font, il existe un certain nombre de recommandations à "sainement" ( par opposition à SO_LINGER
0 timeout, ou se mêler de tcp_tw sysctls) combattre côté client TIME_WAIT
en évitant de créer trop de connexions trop rapidement. Mais ce n'est pas toujours possible, par exemple pour une classe d'applications comme:
- systèmes de surveillance
- générateurs de charge
- procurations
D'un autre côté, je ne comprends même pas du tout comment le côté serveur TIME_WAIT
est utile. La raison TIME_WAIT
est même là, car elle empêche d'injecter des TCP
fragments périmés dans des flux auxquels ils n'appartiennent plus. Pour le côté client, TIME_WAIT
cela est accompli en rendant simplement impossible la création d'une connexion avec les mêmes ip:port
paires que cette connexion périmée aurait pu avoir (les paires utilisées sont verrouillées par TIME_WAIT
). Mais pour le côté serveur, cela ne peut pas être évité car l'adresse locale aura le port d'acceptation, et sera toujours la même, et le serveur ne peut pas (AFAIK, je n'ai que la preuve empirique) refuser la connexion simplement parce que un homologue entrant créerait la même paire d'adresses qui existe déjà dans la table des sockets.
J'ai écrit un programme qui montre que TIME-WAIT côté serveur est ignoré. De plus, comme le test a été fait sur 127.0.0.1, le noyau doit avoir un bit spécial qui lui indique même si c'est du côté serveur ou côté client (car sinon le tuple serait le même).
Source: http://pastebin.com/5PWjkjEf , testé sur Fedora 22, configuration réseau par défaut.
$ gcc -o rtest rtest.c -lpthread
$ ./rtest 44400 s # will do server-side close
Will initiate server close
... iterates ~20 times successfully
^C
$ ss -a|grep 44400
tcp TIME-WAIT 0 0 127.0.0.1:44400 127.0.0.1:44401
$ ./rtest 44500 c # will do client-side close
Will initiate client close
... runs once and then
connecting...
connect: Cannot assign requested address
Ainsi, pour le côté serveur TIME_WAIT
, les connexions sur la même paire de ports peuvent être rétablies immédiatement et avec succès, et pour le côté client TIME-WAIT
, la deuxième itération a connect()
échoué correctement.
Pour résumer, la question est double:
- Le côté serveur ne fait-il
TIME_WAIT
vraiment rien et est-il laissé de cette façon parce que leRFC
requiert? - Est-ce la raison pour laquelle le client recommande d'initialiser close () parce que le serveur
TIME_WAIT
est inutile?
TIME_WAIT
.Réponses:
En termes TCP , côté serveur signifie ici l'hôte qui a le socket en état LISTEN.
Le RFC1122 permet au socket dans l'état TIME-WAIT d'accepter une nouvelle connexion avec certaines conditions
Pour plus de détails sur les conditions, veuillez consulter le RFC1122 . Je m'attends à ce qu'il y ait également un OPEN passif correspondant sur le socket (socket à l'état LISTEN).
OPEN actif (appel de connexion côté client) n'a pas une telle exception et doit donner une erreur lorsque le socket est en TIME-WAIT, conformément à RFC793 .
Ma supposition pour la recommandation sur le client (en termes TCP, l'hôte effectuant une ouverture active, c'est-à-dire une connexion) initiée, est à peu près la même que la vôtre, que dans le cas commun, elle répartit les sockets TIME-WAIT sur plus d'hôtes où il y a une abondance de ressources pour les prises. Dans le cas courant, les clients n'envoient pas de SYN qui réutiliseraient les sockets TIME-WAIT sur le serveur. J'accepte que l'application d'une telle recommandation dépend toujours du cas d'utilisation.
la source
C'est probablement l'exemple le plus clair de ce que TIME-WAIT fait réellement et surtout pourquoi c'est important. Il explique également pourquoi éviter certains des conseils «experts» sur les machines Linux pour «réduire» les TIME-WAIT.
la source
Une session TCP est identifiée par le tupple (sourceIP, sourcePort, destIP, destPort). Par conséquent, TIME_WAIT fonctionne sur chaque connexion TCP.
En ce qui concerne la fermeture, dans certains scénarios, la fermeture du côté client peut réduire les sockets TIME_WAIT sur le serveur, réduisant ainsi légèrement la mémoire. Dans les cas où l'espace de socket peut être épuisé (en raison de l'épuisement du port éphémère) (par exemple, les clients gourmands avec de nombreuses connexions au même serveur), ce problème doit être résolu de n'importe quel côté.
la source
TIME_WAIT
(j'ai mis à jour la question avec ces informations). La référence de @ Khushil ne couvre pas lesTIME_WAIT
cas côté serveur avec suffisamment de détails.Avec un protocole non fiable, vous ne pouvez jamais être sûr que vous avez reçu le dernier message de votre appareil homologue, il est donc dangereux de supposer que votre homologue a raccroché le téléphone assez soudainement. C'est un inconvénient majeur du protocole TCP que seuls 65 000 ports environ peuvent être ouverts simultanément. Mais la solution consiste à passer à une batterie de serveurs, qui s'adapte mieux à la charge, qu'en recyclant rapidement les numéros de port. Du côté client, il est très peu probable que vous manquiez de ports s'il s'agit d'un poste de travail de base.
la source