Question

J'ai lu la référence boost asio, parcouru le didacticiel et examiné certains exemples. Je ne vois toujours pas comment un socket devrait être démoli:

  1. Dois-je appeler close () ou est-ce effectué par le destructeur du socket?
  2. Quand devrais-je appeler shutdown ()
  3. Quels sont les effets de shutdown ()? Je suis conscient que "Désactive l'envoi ou la réception de", mais comment cela se fait-il? À quoi puis-je m'attendre si j'envoie ou reçois en utilisant le socket après l'avoir désactivé?
  4. Quelles erreurs puis-je attendre de close ()
Était-ce utile?

La solution

Comme il s’agit d’une question multiple, je ferai de mon mieux pour répondre à chaque partie de votre satisfaction:

1) Mon expérience avec les sockets ASIO est que le destructeur gère la fermeture du socket. Cependant, je n'ai traité que des sockets TCP. Le meilleur moyen de vérifier ceci est simplement de regarder le code du destructeur pour voir s'il fait quoi que ce soit qui ressemble à une fermeture. Je sais que le code Boost peut être un peu difficile à parcourir. Il peut donc être plus simple de simplement créer un petit exemple de programme qui ouvre un socket UDP puis le détruit. De cette façon, vous pouvez parcourir le code dans un débogueur pour suivre la logique.

Puisque les concepteurs de Boost ont pris cela en compte pour les sockets TCP, j'ai du mal à imaginer qu'ils ne feraient pas la même chose pour les sockets UDP.

2) Appelez shutdown () uniquement lorsque vous pensez qu'il est nécessaire d'empêcher tout code d'exécuter un futur recv et / ou envoyer sur la prise. Ce n'est généralement pas nécessaire, même si je l'ai déjà utilisé sur des sockets TCP pour le forcer à envoyer un RST lorsqu'il est fermé (par opposition à l'arrêt "gracieux" par défaut où les envois en attente sont traités ).

3) Vous pouvez considérer les sockets comme une forme de communication à deux canaux: l’un pour la lecture, l’autre pour l’envoi. Vous pouvez éteindre l’un ou l’autre indépendamment de l’autre, et vous pouvez continuer à utiliser un canal lorsque l’autre est arrêté (c’est-à-dire que vous pouvez toujours recevoir après l’arrêt pour Send et vice versa). Fermer un socket revient à appeler shutdown sur recv et send.

La fermeture de recv empêche simplement votre code de lire plus de données. Si vous essayez de le faire, vous obtiendrez une erreur de socket. De même, si l'autre côté de la connexion tente de vous envoyer des données, il recevra une erreur (désolé de revenir au monde TCP, mais je crois qu'un RST reçoit une réponse de l'expéditeur).

La fermeture pour l'envoi empêche également votre code d'envoyer plus de données. Si la mémoire me sert correctement, cela ressemble à ce qui se passe lorsque vous fermez une socket (un paquet de longueur zéro est envoyé pour signaler à l'autre côté que le canal en question a été arrêté). Toute tentative d'envoi ultérieure renverra une erreur.

4) Vous devrez vérifier votre documentation pour en être certain. MSDN vous donnera une bonne indication, bien que je ne sache pas que je considérerais cela comme faisant autorité.

Autres conseils

D'après les exemples donnés sur le site Web Boost, il semble que vous devriez simplement utiliser close (). Par exemple, regardez celui-ci:

void connection::stop()
{
  socket_.close();
}

Extrait de cette adresse: Serveur HTTP

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