dwww Home | Manual pages | Find package

recvmmsg(2)                   System Calls Manual                  recvmmsg(2)

NOM
       recvmmsg - Recevoir plusieurs message sur une socket

BIBLIOTHÈQUE
       Bibliothèque C standard (libc, -lc)

SYNOPSIS
       #define _GNU_SOURCE         /* Consultez feature_test_macros(7) */
       #include <sys/socket.h>

       int recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen,
                    int flags, struct timespec *timeout);

DESCRIPTION
       L'appel système recvmmsg() est une extension de recvmsg(2) qui permet à
       l'appelant de recevoir plusieurs messages d'une socket en utilisant  un
       seul  appel système. (Cela améliore les performances pour certaines ap-
       plications.) Une autre propriété de ce cette  extension  de  recvmsg(2)
       est la gestion d'une temporisation pour l'opération de réception.

       Le  paramètre  sockfd  est le descripteur de fichier de la socket émet-
       trice.

       L'argument msgvec est un pointeur vers un  tableau  de  structures  mm-
       sghdr. La taille de ce tableau est précisée dans vlen.

       La structure mmsghdr est définie dans <sys/socket.h> comme ceci :

           struct mmsghdr {
               struct msghdr msg_hdr;  /* En-tête du message  */
               unsigned int  msg_len;  /* Nombre d'octets reçus pour l'en-tête */
           };

       Le  champ msg_hdr est une structure  msghdr, conformément à recvmsg(2).
       Le champ msg_len est le nombre d'octets retourné par  le  message  dans
       l'entrée.  Ce  champ  a  la  même  valeur que la valeur de retour de la
       simple commande recvmsg(2) sur l'en-tête.

       L'argument flags contient le OU binaire de la collection des attributs.
       Les attributs sont ceux documentés pour recvmsg(2), plus :

       MSG_WAITFORONE (depuis Linux 2.6.34)
              Activer MSG_DONTWAIT après le premier message reçu.

       L'argument  timeout est un pointeur vers une struct timespec (consultez
       clock_gettime(2)) définissant la temporisation (en secondes et  nanose-
       condes)  pour  l'opération  de  réception  (mais  consultez  la section
       BOGUES !). Cet intervalle sera arrondi à la  granularité  de  l'horloge
       système, et peut être légèrement modifié à cause des délais d'ordonnan-
       cement du noyau. Si timeout est le pointeur nul, l'opération se  bloque
       indéfiniment.

       Un  appel bloquant recvmmsg() bloque jusqu'à la réception de vlsen mes-
       sages ou l'expiration de la temporisation. Un appel  non  bloquant  lit
       autant  de  messages  que  disponibles  (jusqu'à la limite indiquée par
       vlen) et retourne immédiatement.

       Au retour de recvmmsg(), les éléments successifs de msgvec sont  mis  à
       jour  pour  contenir l'information concernant chaque message reçu : les
       champs secondaires de msg_hdr sont mis à jour conformément à recmsg(2).
       La  valeur  de retour de l'appel indique le nombre d'éléments de msgvec
       mis à jour.

VALEUR RENVOYÉE
       En cas du succès, recvmmsg() retourne le nombre de messages reçus  dans
       msgvec ;  Dans le cas contraire, il renvoie -1 et remplit errno avec le
       code d'erreur.

ERREURS
       Les erreurs sont les mêmes que  pour  recvmsg(2),  plus  l'erreur  sui-
       vante :

       EINVAL timeout n'est pas valable.

       Voir aussi BOGUES.

VERSIONS
       L'appel  système recvmmsg() a été ajouté dans Linux 2.6.33. La prise en
       charge dans la glibc a été ajoutée dans la glibc 2.12.

STANDARDS
       recvmmsg() est spécifique à Linux.

BOGUES
       L'argument timeout n'a pas  l'effet  que  l'on  pourrait  attendre.  La
       non-expiration du timeout est vérifiée après la réception de chaque da-
       tagramme, de sorte que si moins de vlen-1 datagrammes sont reçus  avant
       l'expiration  du  timeout, mais qu'aucun datagramme n'est reçu ensuite,
       l'appel restera bloqué indéfiniment.

       Si une erreur survient après qu'au moins un message ait été reçu, l'ap-
       pel  réussit  et  renvoie le nombre de messages reçus. Le code d'erreur
       est prévu pour être renvoyé lors de l'appel suivant à  recvmmsg().  Ce-
       pendant,  dans  l'implémentation  actuelle,  le code d'erreur peut être
       émis en même temps par un événement réseau non lié sur un socket, comme
       un paquet ICMP entrant.

EXEMPLES
       Le  programme  suivant  utilise recvmmsg() pour recevoir plusieurs mes-
       sages sur une socket et les stocker  dans  plusieurs  tampons.  L'appel
       termine si tous les tampons sont remplis ou si le délai indiqué est dé-
       passé.

       Le morceau de code suivant engendre périodiquement des datagrammes  UDP
       contenant un nombre aléatoire :

           $ while true; do echo $RANDOM > /dev/udp/127.0.0.1/1234;
           sleep 0.25; done

       Ces  datagrammes  sont  lus  par  le programme ci-dessous, qui peut par
       exemple afficher la sortie suivante :

           $ ./a.out
           5 messages reçus
           1 11782
           2 11345
           3 304
           4 13514
           5 28421

   Source du programme

       #define _GNU_SOURCE
       #include <arpa/inet.h>
       #include <netinet/in.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <sys/socket.h>
       #include <time.h>

       int
       main(void)
       {
       #define VLEN 10
       #define BUFSIZE 200
       #define TIMEOUT 1
           int                 sockfd, retval;
           char                bufs[VLEN][BUFSIZE+1];
           struct iovec        iovecs[VLEN];
           struct mmsghdr      msgs[VLEN];
           struct timespec     timeout;
           struct sockaddr_in  addr;

           sockfd = socket(AF_INET, SOCK_DGRAM, 0);
           if (sockfd == -1) {
               perror("socket()");
               exit(EXIT_FAILURE);
           }

           addr.sin_family = AF_INET;
           addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
           addr.sin_port = htons(1234);
           if (bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
               perror("bind()");
               exit(EXIT_FAILURE);
           }

           memset(msgs, 0, sizeof(msgs));
           for (size_t i = 0; i < VLEN; i++) {
               iovecs[i].iov_base         = bufs[i];
               iovecs[i].iov_len          = BUFSIZE;
               msgs[i].msg_hdr.msg_iov    = &iovecs[i];
               msgs[i].msg_hdr.msg_iovlen = 1;
           }

           timeout.tv_sec = TIMEOUT;
           timeout.tv_nsec = 0;

           resultat = recvmmsg(sockfd, msgs, VLEN, 0, &timeout);
           if (resultat == -1) {
               perror("recvmmsg()");
               exit(EXIT_FAILURE);
           }

           printf("%d messages reçus\n", retval);
           for (size_t i = 0; i < retval; i++) {
               bufs[i][msgs[i].msg_len] = 0;
               printf("%zu %s", i+1, bufs[i]);
           }
           exit(EXIT_SUCCESS);
       }

VOIR AUSSI
       clock_gettime(2), recvmsg(2), sendmmsg(2), sendmsg(2),  socket(2),  so-
       cket(7)

TRADUCTION
       La  traduction française de cette page de manuel a été créée par Chris-
       tophe Blaess <https://www.blaess.fr/christophe/>, Stéphan  Rafin  <ste-
       phan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, Fran-
       çois Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe  Gué-
       rard  <fevrier@tigreraye.org>,  Jean-Luc  Coulon (f5ibh) <jean-luc.cou-
       lon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>,  Thomas  Huriaux
       <thomas.huriaux@gmail.com>,  Nicolas François <nicolas.francois@centra-
       liens.net>, Florentin Duneau <fduneau@gmail.com>, Simon  Paillard  <si-
       mon.paillard@resel.enst-bretagne.fr>,    Denis   Barbier   <barbier@de-
       bian.org>, David Prévot  <david@tilapin.org>,  Cédric  Boutillier  <ce-
       dric.boutillier@gmail.com>,  Frédéric Hantrais <fhantrais@gmail.com> et
       Jean-Philippe MENGUAL <jpmengual@debian.org>

       Cette traduction est une documentation libre ; veuillez vous reporter à
       la        GNU        General       Public       License       version 3
       ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ concernant  les  conditions
       de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

       Si  vous découvrez un bogue dans la traduction de cette page de manuel,
       veuillez envoyer un message à ⟨debian-l10n-french@lists.debian.org⟩.

Pages du manuel de Linux 6.03   4 décembre 2022                    recvmmsg(2)

Generated by dwww version 1.15 on Sat Jun 29 01:37:54 CEST 2024.