Signatur
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
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);
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);
}
// 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.