243 votes

fermer vs arrêt socket ?

Dans C, j’ai compris que si on ferme une socket, cela signifie la prise sera détruite et peut être réutilisée plus tard.

Que diriez-vous d’arrêt ? La description dit qu'il ferme la moitié d’une connexion duplex à cette socket. Mais elles seront détruite comme cette socket `` appel système ?

219voto

Matthew Flaschen Points 131723

C'est expliqué dans Beej du guide de mise en réseau. shutdown souple de manière à bloquer la communication dans l'une ou les deux directions. Lorsque le deuxième paramètre est SHUT_RDWR, il permet de bloquer l'envoi et de la réception (comme close). Toutefois, close est recommandé de détruire un socket.

Avec shutdown, vous serez toujours en mesure de recevoir des données en attente par les pairs déjà envoyé (merci à Joey Adams pour le signaler).

195voto

Earth Engine Points 1795

Aucune des réponses de dire aux gens comment shutdown et close travaille dans le protocole TCP niveau, il est donc utile d'ajouter ce.

Le standard de connexion TCP résilié par 4 chemin de finalisation:

  1. Une fois que le participant n'avons plus de données à envoyer, il envoie un paquet FIN de l'autre
  2. L'autre partie renvoyer un accusé de réception pour la FIN.
  3. Lorsque l'autre partie a également terminé le transfert de données, il envoie un autre paquet FIN
  4. L'initiale des participants renvoyer un accusé de réception et de finaliser le transfert.

Cependant, il existe un autre "émergentes" pour la fermeture d'une connexion TCP:

  1. Un participant envoie un paquet RST et l'abandon de la connexion
  2. De l'autre côté reçoit un premier puis l'abandon de la connexion ainsi

Dans mon test avec Wireshark, avec les valeurs par défaut des options de socket, shutdown envoie un paquet FIN à l'autre bout, mais c'est tout ce qu'il fait. Jusqu'à ce que l'autre partie de vous envoyer le paquet FIN, vous êtes toujours en mesure de recevoir des données. Une fois que cela s'est produit, votre Receive obtiendrez un 0 résultat de taille. Donc, si vous êtes la première à l'arrêt "envoyer", vous devez fermer le socket une fois que vous avez terminé la réception de données.

D'autre part, si vous appelez close , tandis que la connexion est toujours en vie, un premier paquet va être envoyé à l'autre côté. C'est bon pour les erreurs. Par exemple, si vous pensez que l'autre partie a fourni des données erronées ou il a refusé de fournir des données (OS attaque?), vous pouvez fermer le socket tout de suite.

Mon avis de règles serait:

  1. Toujours shutdown avant close lorsque c'est possible
  2. Si vous avez fini de les recevoir (0 taille des données reçues) avant l'arrêt, fermer la connexion après le dernier d'envoyer des finitions
  3. Si vous voulez fermer la connexion, normalement, à la fermeture de la connexion, et attendre jusqu'à ce que vous recevez un 0 de données de taille, et ensuite fermer le socket.
  4. En tout cas, si timed out ou de toute autre erreur s'est produite il suffit de fermer la socket.

38voto

Milan Points 5703

Il y a certaines limitations close() qui peut être évitée si l'on utilise shutdown() à la place.

close() de résilier les deux sens sur une connexion TCP. Parfois, vous voulez dire à l'autre extrémité que vous avez fini avec l'envoi de données, mais que vous souhaitez toujours recevoir des données.

close() décrémente les descripteurs de comptage de référence (maintenu dans le fichier d'entrée de la table et compte nombre de descripteurs ouverts actuellement, qui font référence à un fichier/socket) et de ne pas fermer le socket/fichier si le descripteur n'est pas 0. Cela signifie que si vous êtes à la bifurcation, le nettoyage se produit seulement après comptage de référence tombe à 0. Avec shutdown() on peut lancer des normal de TCP près de la séquence en ignorant le compte de référence.

Les paramètres sont comme suit:

int shutdown(int s, int how); // s is socket descriptor

int how peut être:

SHUT_RD ou 0 Lui sont interdits

SHUT_WR ou 1 Les envois sont interdits

SHUT_RDWR ou 2 Plus d'envoie et reçoit sont interdits

17voto

Len Holgate Points 12579

Cela peut être de la plate-forme, j'ai un peu de doute, mais de toute façon, la meilleure explication que j'ai vu, c'est ici sur cette page msdn où ils expliquent au sujet de l'arrêt, de s'attarder options de prise de fermeture et d'général séquences de fin de connexion.

En résumé, l'utilisation de l'arrêt d'envoyer une séquence d'arrêt au niveau TCP et l'utilisation à proximité de libérer les ressources utilisées par le support des structures de données dans votre processus. Si vous n'avez pas émis explicite d'une séquence d'arrêt par le moment de l'appel à fermer alors on est mis en place pour vous.

11voto

Toby Points 887

J’ai également eu du succès sous linux en utilisant depuis un pthread pour forcer un autre pthread actuellement bloqué pour abandonner dès le début.

Sous les autres systèmes d’exploitation (OSX au moins), j’ai trouvé la vocation suffisait pour obtenir échouent.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X