Question

J'ai récemment vu un peu de code ressemblant à ceci (avec sock, un objet socket bien sûr):

sock.shutdown(socket.SHUT_RDWR)
sock.close()

Quel est exactement le but d'appeler shutdown sur le socket puis de le fermer? Si cela fait une différence, ce socket est utilisé pour des entrées / sorties non bloquantes.

Était-ce utile?

La solution

En voici un explication :

  

Une fois qu'un socket n'est plus nécessaire,   le programme appelant peut ignorer le   socket en appliquant un sous-programme proche   au descripteur de socket. Si un   prise de livraison fiable a des données   associé quand une fermeture prend   place, le système continue d'essayer   transfert de données. Cependant, si les données sont   toujours non livré, le système se défait   les données. Si l'application   programme n'a aucune utilisation pour tout en attente   les données, il peut utiliser l'arrêt   sous-programme sur le socket avant de   la fermer.

Autres conseils

L'appel de close et de shutdown a deux effets différents sur le socket sous-jacent.

La première chose à souligner est que le socket est une ressource du système d'exploitation sous-jacent et plusieurs processus peuvent avoir un descripteur pour le même socket sous-jacent.

Lorsque vous appelez close , le nombre de descripteurs est décrémenté de un. Si le nombre de descripteurs a atteint zéro, la connexion et la connexion associée passent par la procédure de fermeture normale (envoi effectif d'un FIN / EOF au peer) et le socket est désalloué.

Il est important de noter que si le nombre de descripteurs n'atteint pas zéro, car un autre processus possède toujours un descripteur pour le socket, la connexion n'est pas fermée et le socket n'est pas désalloué.

D'autre part, l'appel de shutdown en lecture et en écriture ferme la connexion sous-jacente et envoie un FIN / EOF à l'homologue, quel que soit le nombre de processus traités par le socket. Toutefois, il ne ne libère pas le socket et vous devez toujours appeler après après.

Explication de la fermeture et de la fermeture: fermeture en douceur (msdn)

Shutdown (dans votre cas) indique à l'autre extrémité de la connexion qu'il n'y a aucune autre intention de lire ou d'écrire dans le socket. Close lib libère la mémoire associée au socket.

Si vous arrêtez l’arrêt, le socket risque de rester immobile dans la pile du système d’exploitation jusqu’à ce que la connexion soit fermée normalement.

Les noms "shutdown" et "close" sont trompeurs, "fermer" et "détruire" souligneraient leurs différences.

il est mentionné directement dans le HOWTO sur la programmation par socket ( py2 / < a href = "http://docs.python.org/3/howto/sockets.html#disconnecting" rel = "noreferrer"> py3 )

  

Déconnexion

     

À proprement parler, vous êtes censé utiliser shutdown sur un socket avant de le fermer .   Le shutdown est un avertissement au socket à l’autre bout. Selon l'argument que vous transmettez, cela peut signifier « je n'enverrai plus, mais j'écouterai quand même » ou « je n'écoute pas, bon débarras! ”.   Cependant, la plupart des bibliothèques de sockets sont tellement habituées aux programmeurs qui négligent d'utiliser cette étiquette que normalement un close est identique à shutdown (); close () .   Ainsi, dans la plupart des cas, un arrêt explicite n’est pas nécessaire.

     

...

Ce code ci-dessus n'est-il pas faux?

L'appel de fermeture juste après l'appel d'arrêt pourrait forcer le noyau à ignorer tous les tampons sortants.

Selon http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable il faut attendre entre l’arrêt et la fermeture jusqu’à ce que la lecture renvoie 0.

il existe plusieurs types d'arrêt: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.shutdown.aspx . * nix est similaire.

Shutdown (1), force le socket n ° à envoyer plus de données

Ceci est utile dans

1- Rinçage du tampon

2- Détection d’erreur étrange

3- Protection sécurisée

Laissez-moi vous expliquer plus, lorsque vous envoyez une donnée de A à B, il n’est pas garanti d’être envoyé à B, il est seulement garanti d'être envoyé au tampon A os, qui à son tour l'envoie au tampon B os

Donc en appelant shutdown (1) sur A, vous videz le tampon de A et une erreur est générée si le tampon n'est pas vide, c.-à-d. que les données n'ont pas encore été envoyées à l'homologue

Cependant, cela est irréversible, vous pouvez donc le faire après avoir complètement envoyé toutes vos données et vous voulez être sûr qu'il est au moins chez le pair mémoire tampon os

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