oracular (2) recvmmsg.2.gz

Provided by: manpages-fr-dev_4.23.1-1_all bug

NOM

       recvmmsg - Recevoir plusieurs message sur un 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'un socket en utilisant un seul appel système. (Cela améliore les performances  pour  certaines
       applications.) 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 le socket émetteur.

       L'argument msgvec est un pointeur vers un tableau de structures mmsghdr. 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  nanosecondes)  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'ordonnancement 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  messages  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 suivante :

       EINVAL timeout n'est pas valable.

       Voir aussi BOGUES.

STANDARDS

       Linux.

HISTORIQUE

       Linux 2.6.33, glibc 2.12.

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 datagramme, 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'appel 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().
       Cependant, 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 messages sur un 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;

           retval = recvmmsg(sockfd, msgs, VLEN, 0, &timeout);
           if (retval == -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), socket(7)

TRADUCTION

       La   traduction   française   de   cette   page   de   manuel   a   été   créée   par  Christophe  Blaess
       <https://www.blaess.fr/christophe/>,   Stéphan   Rafin   <stephan.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.coulon@wanadoo.fr>,   Julien   Cristau
       <jcristau@debian.org>,      Thomas      Huriaux      <thomas.huriaux@gmail.com>,     Nicolas     François
       <nicolas.francois@centraliens.net>,    Florentin    Duneau    <fduneau@gmail.com>,     Simon     Paillard
       <simon.paillard@resel.enst-bretagne.fr>,     Denis    Barbier    <barbier@debian.org>,    David    Prévot
       <david@tilapin.org>,    Cédric    Boutillier     <cedric.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⟩.