RECV
Section : Manuel du programmeur Linux (
2)
Mise à jour de la version anglaise : 29 mai 2008
Index
Menu principal
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, ssize_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_CMSG_CLOEXEC (recvmsg() seulement ; depuis Linux 2.6.23)
-
Positionne l'attribut « close-on-exec » pour le descripteur de fichier
reçu via un descripteur de fichier de domaine Unix en utilisant
l'opération
SCM_RIGHTS
(décrite dans
unix(7)).
Cet attribut est utile pour les mêmes raisons que l'attribut
O_CLOEXEC
de
open(2).
- MSG_DONTWAIT
-
Activer les opérations non bloquantes.
Si l'opération devait bloquer, l'appel échouera avec l'erreur
EAGAIN
(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 transmission 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 {
uint32_t ee_errno; /* numéro d'erreur */
uint8_t ee_origin; /* origine de l'erreur */
uint8_t ee_type; /* type */
uint8_t ee_code; /* code */
uint8_t ee_pad; /* remplissage */
uint32_t ee_info; /* données supplémentaires */
uint32_t ee_data; /* autres données */
/* Des données supplémentaires peuvent suivrent */
};
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 transmise (ceci peut
être vérifié dans le champ
cmsg_len
de
cmsghdr).
À la réception d'une erreur,
MSG_ERRQUEUE
est placé dans
msghdr.
Après la lecture d'une erreur, l'erreur en attente sur la socket
est régénérée en fonction de l'erreur suivante dans la file,
et sera transmise lors de la prochaine opération sur la socket.
- MSG_OOB
-
Cet attribut 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
-
Cet attribut 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
-
Cet attribut 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, entête inclus */
int cmsg_level; /* protocole d'origine */
int cmsg_type; /* type dépendant du protocole*/
/* suivi par
unsigned 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 fichier
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 standard 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 ; voir
signal(7).
- EINVAL
-
Un argument est invalide.
- ENOMEM
-
Impossible d'allouer de la 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 *
actuel 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 dans la glibc actuelle (2.4), le type est
size_t.
EXEMPLE
Un exemple de l'utilisation de
recvfrom()
est donné dans
getaddrinfo(3).
VOIR AUSSI
accept(2),
fcntl(2),
getsockopt(2),
read(2),
select(2),
shutdown(2),
socket(2),
cmsg(3),
sockatmark(3)
TRADUCTION
Ce document est une traduction réalisée par Christophe Blaess
<http://www.blaess.fr/christophe/> le 13 octobre 1996
et révisée le 17 juillet 2008.
L'équipe de traduction a fait le maximum pour réaliser une adaptation
française de qualité. La version anglaise la plus à jour de ce document est
toujours consultable via la commande : « LANG=C man 2 recv ».
N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute
erreur dans cette page de manuel.
Index
- NOM
-
- SYNOPSIS
-
- DESCRIPTION
-
- VALEUR RENVOYÉE
-
- ERREURS
-
- CONFORMITÉ
-
- NOTES
-
- EXEMPLE
-
- VOIR AUSSI
-
- TRADUCTION
-
Dernière mise à jour : 17 juillet 2008