Fonction socket recv () renvoyant des données de longueur égale à 0

Je rencontre une application qui a établi une connexion de socket sur un port numéro 5005 avec un autre périphérique (périphérique matériel avec un serveur Web).

Maintenant, si mon périphérique matériel se déconnecte, je perds la connexion avec le périphérique.

  1. Est-ce que cela signifie que le socket que j’utilisais jusqu’à présent devient invalide?

  2. Est-ce que je reçois un message spécial comme un caractère nul ou quelque chose quand cette déconnexion se produit.

  3. Si la connexion de socket que je devenais invalide, alors pourquoi la fonction de socket recv () jette-t-elle et SOCKET_ERROR. Pourquoi reçois-je plutôt des données de longueur 0?

Merci

Lorsque recv renvoie la valeur 0, cela signifie que la connexion a été fermée.

Voir la page de manuel recv :

Ces appels renvoient le nombre d’octets reçus, ou -1 en cas d’erreur. La valeur de retour sera 0 lorsque l’homologue a effectué un arrêt méthodique.

En réponse à la question n ° 1, oui, le socket est maintenant invalide. Vous devez créer un nouveau socket et une nouvelle connexion pour les communications futures.

modifier

Comme indiqué par valdo ci-dessous, il est également possible d’avoir une connexion TCP à moitié fermée dans laquelle vous ne pouvez plus recevoir, mais vous pouvez continuer à écrire dans le socket jusqu’à ce que vous ayez fini d’envoyer vos données. Voir cet article pour plus de détails: TCP Half-Close . Il ne semble pas que vous ayez cette situation.

En réponse à la question n ° 2, il existe fondamentalement deux manières de détecter un socket fermé. Cela suppose que le socket a subi un arrêt méthodique, c’est-à-dire que l’homologue a appelé shutdown ou close .

La première méthode consiste à lire à partir du socket, auquel cas vous obtenez une valeur de retour de 0. L’autre méthode consiste à écrire dans le socket, ce qui provoquera l’envoi du signal SIG_PIPE indiquant un tuyau cassé.

Afin d’éviter le signal, vous pouvez définir l’option de socket MSG_NOSIGNAL . Dans ce cas, send renverrait -1 et mettrait errno à EPIPE .

D’accord avec Robert S. Barnes. Sauf l’affirmation que le socket est maintenant “invalide”.

C’est toujours valable. Tu peux l’utiliser. Vous pouvez même envoyer des données à l’homologue. La seule chose que vous ne pouvez pas faire est d’appeler recv .

Je suppose que vous utilisez TCP pour communiquer avec votre appareil.

  1. Le socket lui-même est toujours “valide”, mais la connexion a été perdue.

  2. Vous obtenez une valeur de retour de 0 pour recv() lorsque la connexion a été fermée par l’autre hôte (que cette déconnexion soit normale ou pas grave)

  3. Les fonctions de socket sont comme les fonctions C : elles ne jettent pas car elles peuvent être utilisées dans les programmes C , où les exceptions n’existent pas .

Si recv renvoie 0, cela signifie que l’homologue a fermé le socket.

recv ne lancera pas car c’est une fonction C.

S’il y a une erreur, recv retournera -1. Dans ce cas, votre application doit vérifier le type d’erreur. Notez qu’un retour de -1 n’implique pas que l’homologue a fermé son socket.

Étant donné que vous parlez à un serveur Web, je suppose que vous utilisez des sockets TCP.

Répondre:

  1. Les sockets ne deviennent pas invalides en raison d’une déconnexion; ils entrent simplement dans un état déconnecté. Il est toujours prudent d’appeler des opérations de socket sur eux.

  2. Vous ne recevez aucun message spécial lorsque la déconnexion se produit. Si vous appelez recv() de manière bloquante, il retournera une fois déconnecté et le nombre d’octets renvoyés par l’appel ne correspondra pas au nombre d’octets que vous avez demandé.

  3. Il n’ya pas vraiment de réponse à cette question: c’est la façon dont l’API de socket a été implémentée à l’origine, et nous sums bloqués avec cette implémentation puisque tout le monde implémente Berkley Sockets.

Pour corriger de nombreuses anomalies dans les réponses existantes:

  1. Est-ce que cela signifie que le socket que j’utilisais jusqu’à présent devient invalide?

Cela signifie que l’homologue a fermé la connexion ou l’a fermée pour sortie. Votre socket est toujours valide. Vous pouvez appeler recv() nouveau, mais tout ce que vous obtiendrez sera un autre zéro. Vous pouvez aussi appeler send() , et si l’homologue a seulement arrêté la connexion pour la sortie, les données seront envoyées.

  1. Est-ce que je reçois un message spécial comme un caractère nul ou quelque chose lorsque cette déconnexion se produit?

Non, vous obtenez zéro valeur de retour de recv() . C’est pour ça. Il est livré hors bande, pas dans le tampon de données.

  1. Si la connexion de socket que je recv() invalide alors pourquoi la fonction de socket recv() jette-t-elle

Parce que c’est une API C, et qu’il n’y a pas de throws en C, ni d’appels système Unix.

et SOCKET_ERROR.

Parce que ce n’est pas une erreur.

Pourquoi reçois-je plutôt des données de longueur 0?

Vous ne ‘recevez pas de données de longueur 0’. Vous recevez une valeur de retour de zéro au lieu de données.