NOM¶
accept, accept4 - 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.65 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> ».