Start · Sprachen · PHP · Referenz · socket_listen

socket_listen

Funktion

Versetzt einen gebundenen Socket in den Lausch-Zustand, sodass er eingehende Verbindungsanforderungen entgegennehmen kann.

seit PHP 4.1.0 Kategorie: http

Signatur

socket_listen(Socket $socket, int $backlog = 0): bool

Beschreibung

socket_listen() wird nach socket_bind() aufgerufen und versetzt den Socket in den passiven Lausch-Modus. Ab diesem Zeitpunkt kann das Betriebssystem eingehende TCP-Verbindungsanforderungen in einer internen Warteschlange zwischenspeichern, bis sie mit socket_accept() entgegengenommen werden.

Der Parameter $backlog gibt an, wie viele Verbindungen maximal in der Kernel-Warteschlange gepuffert werden dürfen, bevor neue Verbindungen abgewiesen werden. Ein Wert von 0 überlässt dem System die Wahl einer sinnvollen Standardgröße. Für stark belastete Server empfiehlt sich ein höherer Wert (z. B. 128 oder mehr).

socket_listen() ist ausschließlich für verbindungsorientierte Socket-Typen gedacht, also in erster Linie für SOCK_STREAM (TCP) und SOCK_SEQPACKET. Bei verbindungslosen Sockets wie UDP (SOCK_DGRAM) ist diese Funktion nicht anwendbar.

Die typische Abfolge für einen TCP-Server lautet: socket_create()socket_bind()socket_listen() → Schleife mit socket_accept() → Datenverarbeitung.

Parameter

Name Typ Default Beschreibung
$socket Pflicht Socket Ein gültiges Socket-Objekt, das zuvor mit socket_create() erzeugt und mit socket_bind() an eine Adresse gebunden wurde.
$backlog int 0 Maximale Anzahl ausstehender Verbindungen in der Kernel-Warteschlange. Wird 0 übergeben, wählt das Betriebssystem einen systemabhängigen Standardwert. Auf vielen Systemen wird der tatsächliche Wert auf den zulässigen Maximum begrenzt (z. B. SOMAXCONN).

Rückgabewert

Typ
bool
Beschreibung
Gibt true bei Erfolg zurück. Im Fehlerfall wird false zurückgegeben und der Fehlercode kann mit socket_last_error() abgerufen werden.

Beispiele

Einfacher TCP-Echo-Server

<?php
// Socket erstellen
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($server === false) {
    die('socket_create() fehlgeschlagen: ' . socket_strerror(socket_last_error()));
}

// Adresse und Port binden
if (!socket_bind($server, '127.0.0.1', 8080)) {
    die('socket_bind() fehlgeschlagen: ' . socket_strerror(socket_last_error($server)));
}

// In den Lausch-Modus versetzen, bis zu 5 ausstehende Verbindungen
if (!socket_listen($server, 5)) {
    die('socket_listen() fehlgeschlagen: ' . socket_strerror(socket_last_error($server)));
}

echo "Server lauscht auf 127.0.0.1:8080 ...\n";

// Eingehende Verbindung annehmen
$client = socket_accept($server);
if ($client !== false) {
    $nachricht = socket_read($client, 1024);
    echo 'Empfangen: ' . trim($nachricht) . "\n";
    socket_write($client, 'Echo: ' . $nachricht);
    socket_close($client);
}

socket_close($server);
Server lauscht auf 127.0.0.1:8080 ...

Mehrere Verbindungen in einer Schleife verarbeiten

<?php
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($server, '0.0.0.0', 9000);
socket_listen($server, 128); // großer Backlog für stark frequentierte Server

echo "Warte auf Verbindungen auf Port 9000 ...\n";

while (true) {
    $client = socket_accept($server);
    if ($client === false) {
        echo 'Fehler: ' . socket_strerror(socket_last_error($server)) . "\n";
        continue;
    }

    socket_getpeername($client, $ip, $port);
    echo "Verbindung von {$ip}:{$port}\n";

    $antwort = "HTTP/1.1 200 OK\r\nContent-Length: 13\r\n\r\nHello, World!";
    socket_write($client, $antwort);
    socket_close($client);
}
Warte auf Verbindungen auf Port 9000 ...

// Wichtig · Fallstricke

Nur für verbindungsorientierte Sockets: socket_listen() funktioniert ausschließlich mit SOCK_STREAM- und SOCK_SEQPACKET-Sockets. Der Aufruf auf einem UDP-Socket (SOCK_DGRAM) schlägt fehl.

Reihenfolge beachten: socket_listen() muss nach socket_bind() aufgerufen werden. Ein nicht gebundener Socket führt zu einem Fehler.

SO_REUSEADDR empfohlen: Setze die Socket-Option SO_REUSEADDR via socket_set_option() vor dem Binden, um Fehler beim Neustart des Servers zu vermeiden, wenn der Port noch im TIME_WAIT-Zustand ist.

Backlog-Begrenzung: Der tatsächlich verwendete Backlog-Wert kann vom Betriebssystem auf einen systemweiten Maximalwert (z. B. /proc/sys/net/core/somaxconn unter Linux) begrenzt werden.