web-dev-qa-db-fra.com

socket.shutdown vs socket.close

J'ai récemment vu un peu de code qui ressemblait à ceci (avec la chaussette étant un objet socket):

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.

117
Jason Baker

En voici un explication :

Une fois qu'un socket n'est plus nécessaire, le programme appelant peut le supprimer en appliquant un sous-programme close au descripteur de socket. Si des données sont associées à un socket de livraison fiable lorsqu'une fermeture a lieu, le système continue à tenter le transfert de données. Toutefois, si les données ne sont toujours pas livrées, le système les supprime. Si le programme d'application n'a aucune utilisation pour les données en attente, il peut utiliser le sous-programme d'arrêt sur le socket avant de le fermer.

36
Bob Nadler

L'appel de close et 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, il décrémente le nombre de descripteurs de un. Si le nombre de descripteurs a atteint zéro, le socket et la connexion associée passent par la procédure de fermeture normale (envoi effectif d'un FIN/EOF à le pair) 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 pour lire et écrire ferme la connexion sous-jacente et envoie un FIN/EOF à l'homologue, quel que soit le nombre de processus ayant des descripteurs vers le socket. Cependant, il ne le fait pas libérez le socket et vous devez quand même appeler close après.

223
Robert S. Barnes

Explication de l’arrêt et de la fermeture: arrêt gracieux (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. Ensuite, close libère la mémoire associée au socket.

L'omission de l'arrêt peut faire en sorte que le socket reste dans la pile du système d'exploitation jusqu'à ce que la connexion soit correctement fermée.

OMI les noms "shutdown" et "close" sont trompeuses, "fermer" et "détruire" souligneraient leurs différences.

18
Dale Reidy

c'est mentionné directement dans le HOWTO sur la programmation par socket ( py2 / py )

Déconnexion

À proprement parler, vous êtes censé utiliser shutdown sur un socket avant de close le. Le shutdown est un avis au socket de l’autre bout. Selon l'argument que vous transmettez, cela peut vouloir dire “ 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 cet élément Etiquette qui normalement a pour valeur close et shutdown(); close(). Donc, dans la plupart des situations, un arrêt explicite n'est pas nécessaire.

...

7
mykhal

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

L'appel de fermeture directement après l'appel d'arrêt pourrait forcer le noyau à supprimer 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.

5
Christian

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

4
Ray Tayek

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

Ceci est utile dans

1- rinçage du tampon

2- Détection d'erreur étrange

3- Garder en sécurité

Laissez-moi vous expliquer davantage, lorsque vous envoyez une donnée de A à B, il n'est pas garanti qu'elle soit envoyée à B, elle est seulement garantie d'être envoyée 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 des données n'ont pas encore été envoyées à l'homologue.

Quoi qu’il en soit, c’est irréversible, donc vous pouvez le faire après avoir envoyé toutes vos données et que vous voulez être sûr qu’elles se trouvent au moins dans la mémoire tampon du poste de travail homologue

2
user306166