accept, accept4 - nimmt eine Verbindung auf einem Socket an
Standard-C-Bibliothek (
libc,
-lc)
#include <sys/socket.h>
int accept(int sockdd, struct sockaddr *_Nullable restrict adresse,
socklen_t *_Nullable restrict adresslaenge);
#define _GNU_SOURCE /* siehe feature_test_macros(7) */
#include <sys/socket.h>
int accept4(int sockdd, struct sockaddr *_Nullable restrict adresse,
socklen_t *_Nullable restrict adresslaenge, int schalter);
Der Systemaufruf
accept() wird mit den verbindungsbasierten Sockettypen (
SOCK_STREAM und
SOCK_SEQPACKET) benutzt. Er extrahiert die erste
Verbindungsanfrage in der Warteschlange ausstehender Verbindungen für
das wartende Socket
sockdd, erzeugt eine neues verbundenes Socket und
gibt einen neuen Datei-Deskriptor zurück, der sich auf dieses Socket
bezieht. Das neu erstellte Socket ist nicht im Wartezustand. Das
Original-Socket
sockdd wird von diesem Aufruf nicht beeinflusst.
Das Argument
sockdd ist ein Socket, das mit
socket(2) erstellt
wurde, mit
bind(2) an eine lokale Adresse gebunden ist und nach einem
listen(2) auf Verbindungen wartet.
Das Argument
adresse ist ein Zeiger auf eine
sockaddr-Struktur.
Diese Struktur enthält die Adresse des Peer-Sockets, wie sie der
Kommunikationsschicht bekannt ist. Das exakte Format der
zurückgegebenen Adresse
adresse wird durch die Adressfamilie des
Sockets festgelegt (siehe
socket(2) und die jeweiligen
Protokoll-Handbuchseiten). Wenn
adresse NULL ist, wird nichts
eingrtragen; in diesem Fall wird
adresslaenge nicht benutzt und sollte
auch NULL sein.
Das Argument
adresslaenge ist ein Wert-Ergebnis-Argument: Der Aufrufende
muss es initialisieren, um die Größe (in Byte) der Struktur zu
erhalten, auf die
adresse zeigt; bei der Rückkehr wird es die
tatsächliche Größe der Peer-Adresse enthalten.
Die zurückgegebene Adresse wird gekürzt, falls der bereitgestellte
Puffer zu klein ist. In diesem Fall gibt
adresslaenge einen Wert
zurück, der größer als der übergebene Wert ist.
Falls keine ausstehenden Verbindungen in der Warteschlange sind und das Socket
nicht als »nonblocking« gekennzeichnet ist, blockt
accept() den Aufrufenden bis eine Verbindung besteht. Wenn das Socket
als »nonblocking« gekennzeichnet ist und in der Warteschlange
keine ausstehenden Verbindungen enthält, schlägt
accept()
mit dem Fehler
EAGAIN oder
EWOULDBLOCK fehl.
Zur Information über neu auf dem Socket eintreffende Verbindungen, kann
select(2),
poll(2) oder
epoll(7) benutzt werden. Wenn
versucht wird, eine neue Verbindung zu erstellen, wird ein lesbares Ereignis
geliefert und sie können
accept() aufrufen, um ein Socket
für diese Verbindung zu erhalten. Alternativ können Sie das
Socket zum Setzen von
SIGIO veranlassen, wenn es auf dem Socket zu
Aktivität kommt; lesen Sie
socket(7), um Einzelheiten zu
erhalten.
Falls
schalter 0 ist, dann entspricht
accept4()
accept().
Die folgenden Werte können in
schalter bitweise
ODER-verknüpft werden, um ein unterschiedliches Verhalten zu bewirken:
- SOCK_NONBLOCK
- Setzt den Dateistatus-Schalter O_NONBLOCK für
die geöffnete Datei-Deskription (siehe open(2)), auf die
sich der neue Dateideskriptor bezieht. Die Verwendung dieses Schalters
spart zusätzliche Aufrufe von fcntl(2), um das gleiche
Ergebnis zu erreichen.
- SOCK_CLOEXEC
- Setzt den Schalter »Schließen bei
Ausführung« (close-on-exec, FD_CLOEXEC) für
den neuen Dateideskriptor. Lesen Sie die Beschreibung des Schalters
O_CLOEXEC in open(2), um die Gründe zu beleuchten,
warum dies nützlich sein könnte.
Bei Erfolg geben diese Systemaufrufe einen Dateideskriptor für das
akzeptierte Socket (eine nicht negative Ganzzahl) zurück. Bei einem
Fehler wird -1 zurückgegeben,
errno gesetzt, um den Fehler
anzuzeigen, und
adresslaenge verbleibt unverändert.
Die Linux-Version von
accept() (und
accept4()) reichen alle noch
nicht behandelten Netzwerkfehler an das neue Socket als einen Fehlerkode von
accept() weiter. Dieses Verhalten unterscheidet sich von anderen
Implementierungen des BSD-Sockets. Um zuverlässig operieren zu
können, sollte die Anwendung die für das Protokoll nach
accept() definierten Netzwerkfehler aufspüren und sie wie
EAGAIN durch erneutes Probieren verfolgen. Im dem Fall von TCP/IP sind
dies
ENETDOWN,
EPROTO,
ENOPROTOOPT,
EHOSTDOWN,
ENONET,
EHOSTUNREACH,
EOPNOTSUPP und
ENETUNREACH.
-
EAGAIN oder EWOULDBLOCK
- Das Socket ist als »nonblocking«
gekennzeichnet und es sind keine Verbindungen vorhanden, die akzeptiert
werden müssen. POSIX.1-2001 und POSIX.1-2008 erlauben in diesem
Fall auch die Rückgabe beider Fehler und verlangen nicht, dass
diese Konstanten den gleichen Wert haben. Deshalb sollte eine portable
Anwendung beide Möglichkeiten prüfen.
- EBADF
-
sockdd ist kein Deskriptor für eine
geöffnete Datei.
- ECONNABORTED
- Eine Verbindung wurde abgebrochen.
- EFAULT
- Das Argument adresse ist kein beschreibbarer Teil
des Adressraums des Benutzers.
- EINTR
- Der Systemaufruf wurde vor dem Eintreffen einer
gültigen Verbindung durch ein Signal unterbrochen; lesen Sie
signal(7).
- EINVAL
- Das Socket wartet nicht auf Verbindungen oder
adresslaenge ist ungültig (z.B. negativ).
- EINVAL
- (accept4()) ungültiger Wert in
schalter
- EMFILE
- Die Beschränkung pro Prozess der Anzahl offener
Datei-Deskriptoren wurde erreicht.
- ENFILE
- Die systemweite Beschränkung für die
Gesamtzahl offener Dateien wurde erreicht.
-
ENOBUFS, ENOMEM
- Nicht genug Speicher. Dies bedeutet oft, dass die
Speicherreservierung durch die Socket-Pufferbeschränkungen begrenzt
ist und nicht durch den Systemspeicher.
- ENOTSOCK
- Der Dateideskriptor sockdd zeigt nicht auf ein
Socket.
- EOPNOTSUPP
- Das referenzierte Socket ist nicht vom Typ
SOCK_STREAM.
- EPERM
- Firewallregeln die Verbindung verbieten
- EPROTO
- Protokollfehler
Zusätzlich könnten Netzwerkfehler für das neue Socket und
wie sie für das Protokoll definiert sind, zurückgegeben werden.
Verschiedene Linux-Kernel können andere Fehler zurückgeben, wie
ENOSR,
ESOCKTNOSUPPORT,
EPROTONOSUPPORT oder
ETIMEDOUT. Der Wert
ERESTARTSYS kann bei einer Ablaufverfolgung
auftreten.
Der Systemaufruf
accept4() ist seit Linux 2.6.28 verfügbar;
Unterstützung in Glibc ist seit Glibc 2.10 verfügbar.
accept(): POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD (
accept()
erstmalig erschienen in 4.2BSD).
accept4() ist keine Standard-Linux-Erweiterung.
Auf Linux erbt das neue, von
accept() zurückgegebene Socket
nicht die Datei-Statusschalter wie
O_NONBLOCK und
O_ASYNC
vom wartenden Socket. Dieses Verhalten unterscheidet sich von der
vorschriftsmäßigen BSD-Socket-Implementierung. Portable
Programme sollten sich nicht auf Vererbung oder Nicht-Vererbung der
Datei-Statusschalter verlassen und immer explizit alle benötigten
Schalter des Sockets setzen, das sie von
accept()
zurückbekommen.
Es könnte sein, dass nicht immer eine Verbindung wartet, nachdem ein
SIGIO zugestellt wurde oder
select(2),
poll(2) oder
epoll(7) ein Lesbarkeitsereignis zurückgeben, weil die
Verbindung von einem asynchronen Netwerkfehler oder einem anderen Thread
entfernt worden sein könnte bevor
accept() aufgerufen wurde.
Falls dies geschieht, wird der Aufruf das Warten auf die Ankunft der
nächsten Verbindung blockieren. Um sicherzustellen, dass
accept() niemals blockiert, muss beim durchgereichten Socket
sockdd der Schalter
O_NONBLOCK gesetzt werden (siehe
socket(7)).
Bei bestimmten Protokollen, die eine explizite Bestätigung verlangen, wie
DECnet, kann davon ausgegangen werden, dass
accept() nur die
nächste Verbindung aus der Warteschlange holt ohne sie automatisch zu
bestätigen. Die Bestätigung kann ein normaler Lese- oder
Schreibvorgang auf dem neuen Deskriptor mit sich bringen, eine Ablehnung kann
durch ein Schließen des neuen Sockets impliziert werden. Derzeit
verfügt nur DECnet auf Linux über diese Semantik.
In der ursprünglichen BSD-Socket-Implementierung (und in anderen
älteren Systemen) war das dritte Argument von
accept() als
int * deklariert. Ein Entwurf des Standards POSIX.1g wollte es
auf
size_t *C ändern, spätere POSIX-Standards und
Glibc 2.x haben
socklen_t * .
Siehe
bind(2).
bind(2),
connect(2),
listen(2),
select(2),
socket(2),
socket(7)
Die deutsche Übersetzung dieser Handbuchseite wurde von Hanno Wagner
<
[email protected]> und Chris Leick
<
[email protected]> erstellt.
Diese Übersetzung ist Freie Dokumentation; lesen Sie die
GNU
General Public License Version 3 oder neuer bezüglich der
Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.
Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken
Sie bitte eine E-Mail an die
Mailingliste
der Übersetzer