NOM¶
accept - Accepter une connexion sur une socket
SYNOPSIS¶
#include <sys/types.h> /* Consultez NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
#define _GNU_SOURCE /* Consultez feature_test_macros(7) */
#include <sys/socket.h>
int accept4(int sockfd, struct sockaddr *addr,
socklen_t *addrlen, int flags);
DESCRIPTION¶
L'appel système
accept() est employé avec les sockets utilisant
un protocole en mode connecté (
SOCK_STREAM,
SOCK_SEQPACKET). Il extrait la première connexion de la file des
connexions en attente de la socket
sockfd à l'écoute,
crée une nouvelle socket et alloue pour cette socket un nouveau
descripteur de fichier qu'il renvoie. La nouvelle socket n'est pas en
état d'écoute. La socket originale
sockfd n'est pas
modifiée par l'appel système.
L'argument
sockfd est une socket qui a été créée avec
la fonction
socket(2), attachée à une adresse avec
bind(2), et attend des connexions après un appel
listen(2).
L'argument
addr est un pointeur sur une structure
sockaddr. La
structure sera remplie avec l'adresse du correspondant se connectant, telle
qu'elle est connue par la couche de communication. Le format exact du
paramètre
addr dépend du domaine dans lequel la communication
s'établit (consultez
socket(2) et la page de manuel correspondant
au protocole). Quand
addr vaut NULL, rien n'est rempli ; dans ce
cas,
addrlen n'est pas utilisé et doit aussi valoir NULL.
addrlen est un paramètre-résultat : l'appelant doit
l'initialiser de telle sorte qu'il contienne la taille (en octets) de la
structure pointée par
addr, et est renseigné au retour par la
longueur réelle (en octets) de l'adresse remplie.
L'adresse renvoyée est tronquée si le tampon fourni est trop
petit ; dans ce cas,
addrlen renverra une valeur supérieure
à celle fournie lors de l'appel.
S'il n'y a pas de connexion en attente dans la file, et si la socket n'est pas
marquée comme non‐bloquante,
accept() se met en attente
d'une connexion. Si la socket est non‐bloquante, et qu'aucune connexion
n'est présente dans la file,
accept() retourne une erreur
EAGAIN ou
EWOULDBLOCK.
Pour être prévenu de l'arrivée d'une connexion sur une socket, on
peut utiliser
select(2) ou
poll(2). Un événement
« lecture » sera délivré lorsqu'une tentative de
connexion aura lieu, et on pourra alors appeler
accept() pour la
valider. Autrement, on peut configurer la socket pour qu'elle envoie un signal
SIGIO lorsqu'une activité la concernant se produit, consultez
socket(7) pour plus de détails.
Pour certains protocoles nécessitant une confirmation explicite, comme
DECNet,
accept() peut être considéré comme extrayant
simplement la connexion suivante de la file, sans demander de confirmation. On
peut effectuer la confirmation par une simple lecture ou écriture sur le
nouveau descripteur, et le rejet en fermant la nouvelle socket. Pour le
moment, seul DECNet se comporte ainsi sous Linux.
Si
flags vaut 0, alors
accept4() est identique à
accept(). Les valeurs suivantes peuvent être combinées dans
flags par un OU binaire pour obtenir un comportement
différent :
- SOCK_NONBLOCK
- Placer l'attribut d'état de fichier O_NONBLOCK
sur le nouveau descripteur de fichier ouvert. Utiliser cet attribut
économise des appels supplémentaires à fcntl(2) pour
obtenir le même résultat.
- SOCK_CLOEXEC
- Placer l'attribut « close-on-exec »
(FD_CLOEXEC) sur le nouveau descripteur de fichier. Consultez la
description de l'attribut O_CLOEXEC dans open(2) pour savoir
pourquoi cela peut être utile.
VALEUR RENVOYÉE¶
S'ils réussissent, ces appels système renvoient un entier positif ou
nul, qui est un descripteur pour la socket acceptée. En cas d'erreur, ils
renvoient -1 et remplissent
errno avec le code d'erreur.
Traitement des erreurs¶
Sous Linux,
accept() (et
accept4()) renvoie les erreurs
réseau déjà en attente sur la socket comme une erreur de
l'appel système. Ce comportement diffère d'autres
implémentations des sockets BSD. Pour un comportement fiable, une
application doit détecter les erreurs réseau définies par le
protocole après le
accept() et les traiter comme des erreurs
EAGAIN, en réitérant le mécanisme. Dans le cas de
TCP/IP, ces erreurs sont
ENETDOWN,
EPROTO,
ENOPROTOOPT,
EHOSTDOWN,
ENONET,
EHOSTUNREACH,
EOPNOTSUPP, et
ENETUNREACH.
ERREURS¶
- EAGAIN ou EWOULDBLOCK
- La socket est marquée comme étant non bloquante
et aucune connexion n'est présente pour être acceptée.
POSIX.1-2001 permet de renvoyer l'une ou l'autre des erreurs dans ce cas
et n'exige pas que ces constantes aient la même valeur. Une
application portable devrait donc tester les deux possibilités.
- EBADF
- Le descripteur est invalide.
- ECONNABORTED
- Une connexion a été abandonnée.
- EFAULT
- addr n'est pas dans l'espace d'adressage accessible
en écriture.
- EINTR
- L'appel système a été interrompu par
l'arrivée d'un signal avant qu'une connexion valide ne
survienne ; consultez signal(7).
- EINVAL
- La socket n'est pas en attente de connexions, ou
addrlen est invalide (par exemple négatif).
- EINVAL
- (accept4()) flags contient une valeur
incorrecte.
- EMFILE
- La limite du nombre total de descripteurs de fichier
ouverts par processus a été atteinte.
- ENFILE
- La limite du nombre total de fichiers ouverts sur le
système a été atteinte.
- ENOBUFS, ENOMEM
- Pas assez de mémoire disponible. En général,
cette erreur est due à la taille limitée du tampon des sockets,
et non à la mémoire système proprement dite.
- ENOTSOCK
- Le descripteur n'est pas celui d'une socket.
- EOPNOTSUPP
- La socket utilisée n'est pas de type
SOCK_STREAM.
- EPROTO
- Erreur de protocole.
De plus, la version Linux de
accept() peut échouer si :
- EPERM
- Les règles du pare-feu interdisent la connexion.
De plus il peut se produire des erreurs réseau dépendant du protocole
de la socket. Certains noyaux Linux peuvent renvoyer d'autres erreurs comme
ENOSR,
ESOCKTNOSUPPORT,
EPROTONOSUPPORT,
ETIMEDOUT. L'erreur
ERESTARTSYS peut être rencontrée
durant un suivi dans un débogueur.
VERSIONS¶
L'appel système
accept4() est disponible depuis
Linux 2.6.28 ; la prise en charge dans la glibc est disponible
depuis la version 2.10.
accept() : POSIX.1-2001, SVr4, BSD 4.4 (
accept() est
apparu dans BSD 4.2).
accept4() est une extension non standard de Linux.
Avec la version Linux de
accept(), la nouvelle socket n'hérite
pas des attributs comme
O_NONBLOCK et
O_ASYNC de la
socket en écoute. Ce comportement est différent de
l'implémentation BSD de référence. Les programmes portables ne
doivent pas s'appuyer sur cette particularité, et doivent reconfigurer
les attributs sur la socket renvoyée par
accept().
NOTES¶
POSIX.1-2001 ne requiert pas l'inclusion de
<sys/types.h>, et cet
en‐tête n'est pas nécessaire sous Linux. Cependant, il doit
être inclus sous certaines implémentations historiques (BSD), et les
applications portables devraient probablement l'utiliser.
Il n'y a pas nécessairement de connexion en attente après la
réception de
SIGIO ou après que
select(2) ou
poll(2) indiquent quelque chose à lire. En effet la connexion peut
avoir été annulée à cause d'une erreur réseau
asynchrone ou par un autre thread avant que
accept() ne se termine. Si
cela se produit, l'appel bloquera en attendant une autre connexion. Pour
s'assurer que
accept() ne bloquera jamais, la socket
sockfd
transmise doit avoir l'attribut
O_NONBLOCK (consultez
socket(7)).
Le type socklen_t¶
Le troisième argument de
accept() était, à l'origine,
déclaré comme un
int * (ceci dans libc4 et libc5 ainsi que
pour beaucoup d'autres systèmes comme BSD 4.x, SunOS 4, SGI).
Une proposition de standard POSIX.1g l'a modifié en
size_t * et
c'est ce qu'utilise SunOS 5. Les dernières propositions POSIX en ont
fait un
socklen_t *, ce que suivent la Single UNIX Specification et la
glibc2. Pour citer Linus Torvalds :
«
Toute bibliothèque sensée
doit garder
"socklen_t" équivalent à un int. Toute autre chose
invaliderait tout le niveau des sockets BSD. POSIX l'avait d'abord
remplacé par un size_t, et je m'en suis plaint violemment (ainsi que
d'autres heureusement, mais de toute évidence, pas assez). Le
remplacement par un size_t est complètement stupide car size_t a rarement
la même taille qu'un int sur les architectures 64 bits par exemple.
Et il
doit avoir la même taille qu'un "int" parce que
c'était l'interface des sockets BSD. Quoi qu'il en soit, les gens de
POSIX ont compris et ont créé un "socklen_t". Ils
n'auraient jamais dû y toucher, mais une fois commencé, ils ont
décidé de créer un type spécifique, pour des raisons
inavouées (probablement quelqu'un qui ne veut pas perdre la face en
expliquant que le premier travail était stupide et ils ont simplement
renommé leur bricolage). »
EXEMPLE¶
Consultez
bind(2).
VOIR AUSSI¶
bind(2),
connect(2),
listen(2),
select(2),
socket(2),
socket(7)
COLOPHON¶
Cette page fait partie de la publication 3.44 du projet
man-pages Linux.
Une description du projet et des instructions pour signaler des anomalies
peuvent être trouvées à l'adresse
<
http://www.kernel.org/doc/man-pages/>.
TRADUCTION¶
Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a
<
http://po4a.alioth.debian.org/> par l'équipe de traduction
francophone au sein du projet perkamon
<
http://perkamon.alioth.debian.org/>.
Christophe Blaess <
http://www.blaess.fr/christophe/> (1996-2003), Alain
Portal <
http://manpagesfr.free.fr/> (2003-2006). Julien Cristau et
l'équipe francophone de traduction de Debian (2006-2009).
Veuillez signaler toute erreur de traduction en écrivant à
<debian-l10n-french@lists.debian.org> ou 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> ».