Date création : 27-03-2008 20:23:44
 Vous êtes dans : GNU/Linux Astuces / Pages man [Section2 - Appels système]
RECV
Index
- NOM
- SYNOPSIS
- DESCRIPTION
- VALEUR RENVOYÉE
- ERREURS
- CONFORMITÉ
- NOTES
- VOIR AUSSI
- TRADUCTION
NOM
recv, recvfrom, recvmsg - Recevoir un message sur une socket
SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int s, void *buf, size_t len, int flags);
ssize_t recvfrom(int s, void *buf, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen);
ssize_t recvmsg(int s, struct msghdr *msg, int flags);
DESCRIPTION
Les appels système recvfrom() et recvmsg() sont utilisés pour recevoir
des messages depuis une socket, et peuvent servir sur une socket orientée
connexion ou non.
Si from n'est pas NULL, et si le protocole sous-jacent fournit l'adresse
de la source, celle-ci y est insérée. L'argument fromlen est un paramètre
résultat, initialisé à la taille du tampon from, et modifié en retour
pour indiquer la taille réelle de l'adresse enregistrée.
L'appel recv() est normalement utilisé sur une socket connectée (voir
connect(2)) et est équivalent à recvfrom() avec un paramètre from
NULL.
Ces trois routines renvoient la longueur du message si elles réussissent. Si
un message est trop long pour tenir dans le tampon, les octets
supplémentaires peuvent être abandonnés suivant le type de socket utilisé.
Si aucun message n'est disponible sur la socket, les fonctions de réception
se mettent en attente, à moins que la socket soit non bloquante (voir
fcntl(2)) auquel cas la valeur -1 est renvoyée, et errno est
positionnée à EAGAIN. Les fonctions de réception renvoient normalement
les données disponibles sans attendre d'avoir reçu le nombre exact réclamé.
Les appels système select(2) ou poll(2) peuvent permettre de
déterminer si des données supplémentaires sont disponibles.
L'argument flags de l'appel recv() est constitué par un OU binaire
entre une ou plusieurs des valeurs suivantes :
- MSG_DONTWAIT
-
Activer les opérations non-bloquantes. Si l'opération devait bloquer,
EAGAIN sera renvoyé (on peut aussi activer ce comportement avec l'option
O_NONBLOCK de la fonction F_SETFL de fcntl(2)).
- MSG_ERRQUEUE
-
Cet attribut demande que les erreurs soient reçues depuis la file d'erreur
de la socket. Les erreurs sont transmises dans un message annexe dont le
type dépend du protocole (IP_RECVERR pour IPv4). Il faut alors fournir un
tampon de taille suffisante. Voir cmsg(3) et ip(7) pour plus de
détails. Le contenu du paquet original qui a causé l'erreur est passé en
tant que données normales dans msg_iovec. L'adresse de destination
originale du datagramme ayant causé l'erreur est fournie dans msg_name.
-
Pour les erreurs locales, aucune adresse n'est passée (ceci peut être
vérifié dans le membre cmsg_len de cmsghdr). À la réception d'une
erreur, MSG_ERRQUEUE est placé dans msghdr. Après réception d'une
erreur, l'erreur en attente sur la socket est régénérée en fonction de la
prochaine erreur dans la file, et sera transmise lors de l'opération
suivante sur la socket.
L'erreur est contenue dans une structure sock_extended_err :
#define SO_EE_ORIGIN_NONE 0
#define SO_EE_ORIGIN_LOCAL 1
#define SO_EE_ORIGIN_ICMP 2
#define SO_EE_ORIGIN_ICMP6 3
struct sock_extended_err
{
u_int32_t ee_errno; /* numéro d'erreur */
u_int8_t ee_origin; /* origine de l'erreur */
u_int8_t ee_type; /* type */
u_int8_t ee_code; /* code */
u_int8_t ee_pad; /* remplissage */
u_int32_t ee_info; /* données supplémentaires*/
u_int32_t ee_data; /* autres données */
/* Des données supplémentaires peuvent suivre */
};
struct sockaddr *SO_EE_OFFENDER(struct sock_extended_err *);
-
ee_errno contient le code errno de l'erreur en file. ee_origin est
le code d'origine de l'erreur. Les autres champs sont spécifiques au
protocole. La macro SOCK_EE_OFFENDER renvoie un pointeur sur l'adresse de
l'objet réseau ayant déclenché l'erreur, à partir d'un pointeur sur le
message. Si l'adresse n'est pas connue, le membre sa_family de la
structure sockaddr contient AF_UNSPEC et les autres champs de la
structure sockaddr sont indéfinis. Le contenu du paquet ayant déclenché
l'erreur est transmis en données normales.
-
Pour les erreurs locales, aucune adresse n'est passée (ceci peut être
vérifié dans le membre cmsg_len de cmsghdr). À la réception d'une
erreur, MSG_ERRQUEUE est placé dans msghdr. Après réception d'une
erreur, l'erreur en attente sur la socket est régénérée en fonction de la
prochaine erreur dans la file, et sera transmise lors de l'opération
suivante sur la socket.
- MSG_OOB
-
Cette option permet la lecture des données hors-bande qui ne seraient
autrement pas placées dans le flux de données normales. Certains protocoles
placent ces données hors-bande en tête de la file normale, et cette option
n'a pas lieu d'être dans ce cas.
- MSG_PEEK
-
Cette option permet de lire les données en attente dans la file sans les
enlever de cette file. Ainsi une lecture ultérieure renverra à nouveau les
mêmes données.
- MSG_TRUNC
-
Renvoyer la longueur réelle du paquet, même s'il était plus long que le
tampon transmis. Valide uniquement pour les sockets paquets.
- MSG_WAITALL
-
Cette option demande que l'opération de lecture soit bloquée jusqu'à ce que
la requête complète soit satisfaite. Toutefois, la lecture peut renvoyer
quand même moins de données que prévu si un signal est reçu, ou si une
erreur ou une déconnexion se produisent.
L'appel recvmsg() utilise une structure msghdr pour minimiser le
nombre de paramètres à fournir directement. Cette structure a la forme
suivante, définie dans <sys/socket.h> :
struct msghdr {
void *msg_name; /* adresse optionnelle */
socklen_t msg_namelen; /* taille de l'adresse */
struct iovec *msg_iov; /* tableau scatter/gather */
size_t msg_iovlen; /* # éléments dans msg_iov */
void *msg_control; /* métadonnées, voir ci-dessous */
socklen_t msg_controllen; /* taille du tampon de métadonnées */
int msg_flags; /* attributs du message reçu */
};
Ici msg_name et msg_namelen spécifient l'adresse d'origine si la
socket n'est pas connectée ; msg_name peut être un pointeur nul si le
nom n'est pas nécessaire. msg_iov et msg_iovlen décrivent les tampons
de réception comme décrit dans readv(2). msg_control, de longueur
msg_controllen, pointe sur un tampon utilisé pour les autres messages
relatifs au protocole, ou à d'autres données annexes. Lorsqu'on invoque
recvmsg, msg_controllen doit contenir la longueur disponible dans le
tampon msg_control ; au retour il contiendra la longueur de la séquence
de message de contrôle.
Les messages ont la forme
struct cmsghdr {
socklen_t cmsg_len; /* nombre d'octets de données, y compris l'en-tête */
int cmsg_level; /* protocole d'origine */
int cmsg_type; /* type dépendant du protocole */
/* suivi de
u_char cmsg_data[]; */
};
Les données de service ne doivent être manipulées qu'avec les macros de
cmsg(3).
À titre d'exemple, Linux utilise ce mécanisme pour transmettre des erreurs
étendues, des options IP, ou des descripteurs de fichiers sur des sockets
Unix.
Le champ msg_flags du msghdr est rempli au retour de recvmsg(). Il
peut contenir plusieurs attributs :
- MSG_EOR
-
indique une fin d'enregistrement, les données reçues terminent un
enregistrement (utilisé généralement avec les sockets du type
SOCK_SEQPACKET).
- MSG_TRUNC
-
indique que la portion finale du datagramme a été abandonnée car le
datagramme était trop long pour le tampon fourni.
- MSG_CTRUNC
-
indique que des données de contrôle ont été abandonnées à cause d'un manque
de place dans le tampon de données annexes.
- MSG_OOB
-
indique que des données hors-bande ont été reçues.
- MSG_ERRQUEUE
-
indique qu'aucune donnée n'a été reçue, sauf une erreur étendue depuis la
file d'erreurs.
VALEUR RENVOYÉE
Ces fonctions renvoient le nombre d'octets reçus si elles réussissent, ou -1
si elles échouent. La valeur de retour sera 0 si le pair a effectué un arrêt
normal.
ERREURS
Il y a des erreurs standards déclenchées par le niveau socket, et des
erreurs supplémentaires spécifiques aux protocoles. Voyez leurs pages de
manuel.
- EAGAIN
-
La socket est non-bloquante et aucune donnée n'est disponible, ou un délai
de timeout a été indiqué, et il a expiré sans que l'on ait reçu quoi que ce
soit.
- EBADF
-
L'argument s n'est pas un descripteur valide.
- ECONNREFUSED
-
Un hôte distant a refusé la connexion réseau (généralement parce qu'il
n'offre pas le service demandé).
- EFAULT
-
Un tampon pointe en dehors de l'espace d'adressage accessible.
- EINTR
-
Un signal a interrompu la lecture avant que des données soient disponibles.
- EINVAL
-
Un argument invalide a été transmis.
- ENOMEM
-
Pas assez de mémoire pour recvmsg().
- ENOTCONN
-
La socket est associée à un protocole orienté connexion et n'a pas encore
été connectée (voir connect(2) et accept(2)).
- ENOTSOCK
-
L'argument s ne correspond pas à une socket.
CONFORMITÉ
BSD 4.4 (ces fonctions sont apparues dans BSD 4.2), POSIX.1-2001.
POSIX.1-2001 décrit seulement les drapeaux MSG_OOB, MSG_PEEK, et
MSG_WAITALL.
NOTES
Les prototypes fournis concernent la glibc 2. Les Spécifications Single Unix
les définissent, mais le type de retour est « ssize_t » (alors que BSD 4.x, libc4 , et libc5 renvoient un « int »). L'argument flags est un « int » dans BSD 4.x, mais « unsigned int » dans libc4 et
libc5. L'argument len est un « int » dans BSD 4.x, mais un « size_t » dans libc4 et libc5. L'argument fromlen est un « int * » dans BSD 4.x, libc4 et libc5. Le type « socklen_t * » a été inventé par POSIX. Voir
également accept(2).
Selon POSIX.1-2001, le champ msg_controllen de la structure msghdr
devrait être de type socklen_t, mais il a actuellement le type size_t
dans la glibc (version 2.4).
VOIR AUSSI
fcntl(2), getsockopt(2), read(2), select(2), shutdown(2),
socket(2), cmsg(3), sockatmark(3)
TRADUCTION
Cette page de manuel a été traduite et mise à jour par
Christophe Blaess <http://www.blaess.fr/christophe/> entre 1996 et 2003,
puis par Alain Portal <aportal AT univ-montp2 DOT fr> jusqu'en 2006.
La traduction de cette page de manuel est basée sur les traductions
disponibles sur http://manpagesfr.free.fr/,
mais est gérée par l'équipe francophone de traduction de Debian
au travers de la liste de discussion debian-l10n-french.
Veuillez signaler toute erreur de traduction par un rapport de bogue sur
le paquet manpages-fr.
Vous pouvez toujours avoir accès à la version anglaise de ce document en
utilisant la commande
« man -L C <section> <page_de_man> ».
|