Question

Je lisais sur l'utilisation de l'option de socket SO_LINGER intentionnellement « assassiner » l'état de temps attendre en réglant le temps de Linger à zéro. L'auteur du livre va alors à dire que nous ne devrions jamais faire cela et en général que nous ne devrions jamais interférer avec l'état de temps attendre. puis il recommande immédiatement d'utiliser l'option SO_REUSEADDR pour contourner l'état d'attente de temps.

Ma question est, quelle est la différence? Dans les deux cas, vous êtes mettre fin prématurément l'état d'attente en temps et en prenant le risque de recevoir des segments en double. Pourquoi est l'un bon et l'autre mauvais?

Était-ce utile?

La solution 2

Je l'ai fait un peu plus la lecture et c'est ma compréhension de ce qui se passe (je l'espère correcte):

Lorsque vous appelez à proximité sur un socket qui a SO_REUSEADDR ensemble (ou votre application se bloque) la séquence suivante se produit:

  1. TCP envoie les données restantes dans le tampon d'envoi et FIN
  2. Si près a été appelé il retourne immédiatement sans indiquée si les données restantes a été livré avec succès.
  3. Si les données ont été envoyées par les pairs envoie une donnée ACK
  4. Le pair envoie un accusé de réception de la FIN et envoie son propre paquet FIN
  5. FIN est Acked de l'homologue et les ressources socket sont désallouée.
  6. La prise ne pénètre pas dans TIME-WAIT.

Lorsque vous fermez une prise avec le temps SO_LINGER à zéro:

  1. TCP efface toutes les données dans le tampon d'émission
  2. TCP envoie un paquet RST au pair
  3. La ressource de socket sont désallouée.
  4. La prise ne pénètre pas dans TIME-WAIT

Alors au-delà du fait que la mise Linger à zéro est un style hack et mauvais, il est aussi de mauvaises manières car il ne passe pas par un arrêt propre de la connexion.

Autres conseils

TIME_WAIT est tout à fait normal. Il se produit après une FIN TCP sur le côté local suivi d'un TCP FIN ACK de l'emplacement distant. Dans TIME_WAIT vous fait qu'attendre des paquets errants pour arriver à l'adresse locale. Cependant, s'il y a un paquet perdu ou égaré alors assurez-vous que TIME_WAIT TTL ou « temps de vivre » avant d'utiliser expires l'adresse à nouveau.

Si vous utilisez SO_REUSEADDR alors vous dites en gros, je suppose qu'il n'y a pas de paquets errants. Ce qui est de plus en plus probable avec modernes, fiables, des réseaux TCP. Bien qu'il soit encore possible, il est peu probable.

Réglage SO_LINGER à zéro vous amène à lancer une proximité anormale, également appelé « claquant la connexion. » Ici, vous ne respectez pas TIME_WAIT et ignorer la possibilité d'un paquet parasite.

Si vous voyez FIN_WAIT_1 cela peut causer des problèmes, comme l'emplacement distant n'a pas envoyé TCP FIN ACK en réponse à votre FIN. Ainsi, le processus a été tué ou le TCP FIN ACK a été perdu en raison d'une partition de réseau ou une mauvaise voie.

Quand vous voyez CLOSE_WAIT vous avez un problème, ici vous des raccords non étanches que vous n'êtes pas envoyer le TCP FIN ACK lorsque le TCP FIN donné.

J'utiliser SO_REUSEADDR à un port local pour lequel un autre programme avait déjà une connexion ouverte sur wildcard bind (). Il se trouve cette utilisation particulière ne causera jamais un problème aussi longtemps que pas deux prises essayez d'écouter () sur le même combo adr / port en même temps.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top