ACCEPT(2) Manuel du programmeur Linux ACCEPT(2)
NOM
accept - Accepter une connexion sur une socket.
SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>
int accept(int sock, struct sockaddr *adresse, socklent_t
*longueur);
DESCRIPTION
accept est utilisé généralement avec des processus
serveurs orientés-connexion.
L'argument sock est une socket qui a été créée avec la
fonction socket(2). On lui a affecté une adresse avec
bind(2). Enfin on a indiqué au système, avec listen(2)
qu'elle désirait recevoir des connexions entrantes.
L'appel système accept extrait la première connexion de la
file des connexions en attente, crée une nouvelle socket
avec les mêmes propriétés que sock et alloue un nouveau
descripteur de fichier pour cette socket.
S'il n'y a pas de connexion en attente dans la file, et si
la socket est 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 décrite ci-dessous.
Une socket acceptée ne peut pas être utilisée pour
accepter de nouvelles connexions. La socket originale sock
reste ouverte.
L'argument adresse est un paramètre résultat qui est ren
seigné avec l'adresse de l'entité se connectant, telle
qu'elle est connue par la couche de communication. Le
format exact du paramètre adresse est fonction du domaine
dans lequel la communication s'établit. Le paramètre-
resultat longueur est renseigné avec la longueur (en
octets) de l'adresse retournée. Ce paramètre doit ini
tialement contenir la longueur du paramètre adresse.
Cet appel système est utilisé avec les sockets utilisant
un protocole en mode connecté, généralement du type
SOCK_STREAM.
Lorsque l'on désire accepter des connexions sur plusieurs
sockets simultanément, il est important de ne pas rester
bloqué en attente avec l'appel accept sur une seule
d'entre elles. Il est alors possible d'utiliser l'appel-
système select(2) sur l'ensemble des sockets pour déter
miner la disponibilité des données à lire, et d'effectuer
ensuite l'appel accept sur celles qui ont effectivement
reçu des demandes de connexion.
Linux 18 Mai 1999 1
ACCEPT(2) Manuel du programmeur Linux ACCEPT(2)
Pour certains protocoles nécessitant une confirmation
explicite, comme ISO ou DATAKIT, accept peut être con
sidéré comme extrayant simplement la connexion suivante de
la file, sans demander de confirmation. Cette confirmation
peut être effectuée par une simple lecture ou écriture sur
le nouveau descripteur de fichier, et un rejet peut être
effectué en fermant simplement la nouvelle socket.
On peut obtenir les données utilisateur d'une connexion
sans confirmation, en effectuant un appel-système
recvmsg(2) avec un msg_iovlen valant zéro, et un msg_con
trollen non nul, ou en effectuant une demande getsock
opt(2).
De même on peut fournir des informations sur un rejet de
connexion en utilisant un appel sendmsg(2) en fournissant
uniquement les données de contrôle, ou en appelant set
sockopt(2).
VALEUR RENVOYÉE
accept renvoie -1 en cas d'erreur. S'il réussit il renvoie
un entier non-négatif, constituant un descripteur pour la
nouvelle socket.
ERREURS
EBADF sock est un descripteur invalide.
ENOTSOCK
sock est un descripteur de fichier, pas de socket.
EOPNOTSUPP
La socket de référence n'est pas de type
SOCK_STREAM.
EFAULT adresse pointe en-dehors de l'espace d'adressage
accessible.
EWOULDBLOCK
La socket est non-bloquante et aucune connexion
n'est présente dans la file.
EXEMPLE
Un scénario typique de mise en oeuvre de serveur orienté
connexion est le suivant :
int pnum;
int sock;
int nouvelle;
sock = socket (famille, type, 0);
if (sock < 0) {
perror ("socket");
exit (1);
Linux 18 Mai 1999 2
ACCEPT(2) Manuel du programmeur Linux ACCEPT(2)
}
if (bind (sock, & mon_adresse, longueur_adresse) < 0) {
perror ("bind");
exit (1);
}
if (listen (sock, 5) < 0) {
perror ("listen");
exit (1);
}
while (1) {
nouvelle = accept (sock, & adresse_client, & lg_adresse_client);
if (nouvelle < 0) {
perror ("accept");
exit (1);
}
if ((pnum = fork ()) == 0) {
/* Processus fils */
close (sock);
Traiter_le_client (nouvelle);
exit (0);
}
if (pnum > 0) {
/* Processus père */
close (nouvelle);
/* Attendre la connexion suivante */
continue;
}
perror ("fork");
exit (1);
}
CONFORMITÉ
SVr4, BSD 4.4. La fonction accept est apparue dans BSD
4.2. IRIX fournit des conditions d'erreur supplémentaires
EMFILE et ENFILE. Solaris documente les erreurs
supplémentaires EINTR, ENODEV, ENOMEM, ENOSR et EPROTO.
NOTE
Le troisième argument de accept était, à l'origine,
déclaré comme un `int *' (et c'est le cas dans libc4 et
libc5 ainsi que pour beaucoup d'autres systèmes comme BSD
4.*, SunOS 4, SGI). Une proposition de standard POSIX
1003.1g l'a modifié en `size_t *' et c'est ce qu'utilise
SunOS. Les dernières propositions POSIX en ont fait un
`socklen_t *', ce que suivent les spécifications Single
Unix, 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
Linux 18 Mai 1999 3
ACCEPT(2) Manuel du programmeur Linux ACCEPT(2)
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 bien entendu pas tant que ça). Le rem
placement par un size_t est complètement inutile car
size_t à exactement la même taille qu'un int sur les
architectures 64 bits par exemple. Et il a la même taille
qu'un "int" parce que c'était ainsi qu'étaient définies
les sockets BSD. Finalement, les gens de POSIX ont com
pris 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 encore inavouées (il
y a 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).
VOIR AUSSI
bind(2), connect(2), listen(2), select(2), socket(2)
TRADUCTION
Christophe Blaess, 1997.
Linux 18 Mai 1999 4