accept

Wie sieht's aus?

#include <sys/types.h>
#include <sys/socket.h>

int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
    

Was tut's?

accept() holt eine eingehende Verbindung aus der Warteschlange. Der Rückgabewert stellt hier den neuen Socket dar, der diese Verbindung bezeichnet. Nachdem ein Client mit accept() angenommen wurde, ist die Verbindung vollständig aufgebaut und kann für alle weiteren Operationen verwendet werden. Er sollte ebenfalls mit close() geschlossen werden (um den Client wieder "loszulassen", falls er darauf wartet, daß der Server die Verbindung kappt).

Unter Windows wird im Fehlerfall INVALID_SOCKET zurückgegeben, unter UNIX ist es wie bei allen Syscalls -1.

Was machen die Parameter?

Der erste Parameter gibt den Socket im Listen-Status an, auf dem die Verbindung eingegangen ist (anders formuliert: der Socket, von dem man den neuen Client abholen möchte).

Der zweite Parameter ist ein Ergebnisparameter. In diesem steht nach erfolgreichem Annehmen die Adresse sowie die Port-Nummer des anderen Endes der Verbindung drin. Man darf hier NULL angeben, wenn man an diesen Daten nicht interessiert ist.

Der dritte Parameter ist auch ein Ergebnisparameter, der jedoch vorbelegt werden muß. Das heißt: er muß beim Aufruf der Funktion die Länge der Struktur beinhalten, und kann vom Kernel beschrieben werden (muß aber nicht passieren). Daher ist hier unbedingt ein Zeiger auf eine wirklich existierende Variable zu nehmen. Im Regelfall sollte hier nach dem Aufruf das Gleiche wie vorher drinstehen (es ist schließlich unwahrscheinlich, daß auf einem lauschenden Socket der Domain PF_INET etwas anbeisst, das nicht auch in PF_INET liegt), wer Spaß dran hat, kann ja das Ergebnis gegen die Grösse einer struct sockaddr_in{} testen. Wenn man als zweiten Parameter NULL angegeben hat, so muß hier 0 angegeben werden.

Wie verwende ich es?

struct sockaddr_in cli;
socklen_t cli_size;

cli_size = sizeof(cli);
if ((c = accept(s, (struct sockaddr*) &cli, &cli_size)) == -1)
{
    /* bei nicht automatisch neustartenden Systemcalls
     * if (errno == EINTR)
     *     ...
     */
    perror("accept() failed");
    return 4;
}