ACCEPT(2) | Linux-Programmierhandbuch | ACCEPT(2) |
accept, accept4 – nimmt eine Verbindung auf einem Socket an
#include <sys/types.h> /* Siehe ANMERKUNGEN */ #include <sys/socket.h>
int accept(int sockfd, struct sockaddr *adresse, socklen_t *adresslaenge); #define _GNU_SOURCE /* siehe feature_test_macros(7) */ #include <sys/socket.h>
int accept4(int sockfd, struct sockaddr *adresse, socklen_t *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 sockfd, 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 sockfd wird von diesem Aufruf nicht beeinflusst.
Das Argument sockfd 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:
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 entsprechend gesetzt 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.
Zusätzlich könnte Linux-accept() fehlschlagen, falls:
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 Version 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.
POSIX.1-2001 erfordert nicht, dass <sys/types.h> eingebunden wird. Diese Header-Datei ist in Linux nicht erforderlich. Allerdings benötigen einige historische Implementierungen (BSD) diese Header-Datei. Es wird empfohlen, sie für portierbare Anwendungen einzubinden.
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 sockfd 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)
Diese Seite ist Teil der Veröffentlichung 5.10 des Projekts Linux-man-pages. Eine Beschreibung des Projekts, Informationen, wie Fehler gemeldet werden können sowie die aktuelle Version dieser Seite finden sich unter https://www.kernel.org/doc/man-pages/.
Die deutsche Übersetzung dieser Handbuchseite wurde von Hanno Wagner <wagner@bidnix.bid.fh-hannover.de> und Chris Leick <c.leick@vollbio.de> 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.
11. April 2020 | Linux |