BEZEICHNUNG¶
accept – nimmt eine Verbindung auf einem Socket an
ÜBERSICHT¶
#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);
BESCHREIBUNG¶
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 wird
adresslaenge einen
größeren Wert zurückgeben, als der beim Aufruf übergebene.
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) oder
poll(2) 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.
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.
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 Datei-Statusschalter O_NONBLOCK für
den neu geöffneten Dateideskriptor. Die Benutzung dieses Schalters
speichert zusätzliche Aufrufe nach fcntl(2), um das gleiche
Ergebnis zu erzielen.
- SOCK_CLOEXEC
- Setzt den Schalter Schließen-beim-Ausführen
FD_CLOEXEC für den neu geöffneten Datei-Deskriptor. Lesen
Sie die Beschreibung des Schalters O_CLOEXEC in open(2), um
die Gründe zu beleuchten, warum dies nützlich sein
könnte.
RÜCKGABEWERT¶
Bei Erfolg geben diese Systemaufrufe eine nicht negative Ganzzahl zurück,
die kein Deskriptor für das akzeptierte Socket ist. Bei einem Fehler wird
-1 zurückgegeben und
errno entsprechend gesetzt.
Fehlerbehandlung¶
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.
FEHLER¶
- EAGAIN oder EWOULDBLOCK
- Das Socket ist als »nonblocking« gekennzeichnet
und es sind keine Verbindungen vorhanden, die akzeptiert werden
müssen. POSIX.1-2001 erlaubt in diesem Fall auch die Rückgabe
beider Fehlers und verlangt nicht, dass diese Konstanten den gleichen Wert
haben. Deshalb sollte eine portable Anwendung beide Möglichkeiten
prüfen.
- EBADF
- Der Deskriptor ist ungültig.
- 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 offener Datei-Deskriptoren pro
Prozess wurde erreicht.
- ENFILE
- Die Systembeschränkung für die Summe offener
Datei 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 Deskriptor referenziert eine Datei und kein
Socket.
- EOPNOTSUPP
- Das referenzierte Socket ist nicht vom Typ
SOCK_STREAM.
- EPROTO
- Protokollfehler
Zusätzlich könnte Linux-
accept() fehlschlagen, falls:
- EPERM
- Firewallregeln die Verbindung verbieten
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.
VERSIONEN¶
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, 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.
ANMERKUNGEN¶
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) oder
poll(2) 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)).
Der Typ socklen_t¶
Das dritte Argument von
accept() wurde ursprünglich als ein
int
* deklariert (und ist dies unter Libc4, Libc5 und vielen anderen Systemen,
wie 4.x BSD, SunOS 4, SGI); ein Entwurf des POSIX.1g-Standards wollte es in
ein
size_t * ändern und das ist es in SunOS 5. Neuere
POSIX-Entwürfe benutzen
socklen_t * und daher die »Single
UNIX Specification« und Glibc2. Zitat Linus Thorvalds:
»Bei jeder vernünftigen Bibliothek _muss_ »socklen_t« die
gleiche Größe wie »int« haben. Alles andere zerstört
jedes weitere BSD-Socket-Ebenen-Zeug. POSIX
machte daraus anfangs ein
»size_t« und ich (und hoffentlich andere, aber offenbar nicht allzu
viele) reklamierten das durchaus lautstark. Dies zu einem »size_t«
zu machen ist genau deshalb nicht in Ordnung, weil »size_t« zum
Beispiel sehr selten auf 64-Bit-Architekturen die gleiche Größe wie
»int« hat. Und es
muss die gleiche Größe wie
»int« haben, weil genau das die BSD-Socket-Schnittstelle ist.
Irgendwie bekamen die POSIX-Leute einen Hinweis und erstellten
»socklen_t«. Sie sollten es ursprünglich nicht anfassen, aber
sobald sie es taten, wollten sie aus einem unerfindlichen Grund einen
benannten Typ haben (wahrscheinlich wollte jemand sein Gesicht wahren wegen
der ursprünglichen Dummheit, so dass sie nur stillschweigend ihren
Fehlgriff umbenannten).«
BEISPIEL¶
Siehe
bind(2).
SIEHE AUCH¶
bind(2),
connect(2),
listen(2),
select(2),
socket(2),
socket(7)
KOLOPHON¶
Diese Seite ist Teil der Veröffentlichung 3.42 des Projekts Linux-
man-pages. Eine Beschreibung des Projekts und Informationen, wie Fehler
gemeldet werden können, finden sich unter
http://www.kernel.org/doc/man-pages/.
ÜBERSETZUNG¶
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 <debian-l10n-german@lists.debian.org>.