Start · Sprachen · PHP · Referenz · stream_socket_server

stream_socket_server

Funktion

Erzeugt einen Internet- oder Unix-Domain-Server-Socket und gibt eine Stream-Ressource zurück, die auf eingehende Verbindungen wartet.

seit PHP 5.0.0 Kategorie: io

Signatur

stream_socket_server(string $address, int &$error_code = null, string &$error_message = null, int $flags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, ?resource $context = null): resource|false

Beschreibung

stream_socket_server() öffnet einen Server-Socket für das angegebene Protokoll (TCP, UDP, Unix-Domain-Socket etc.) und bindet ihn an die übergebene Adresse. Die Funktion ist die moderne, stream-basierte Alternative zu socket_create() und integriert sich nahtlos in PHPs Stream-Wrapper-System.

Die Adresse folgt dem Schema transport://host:port, z. B. tcp://0.0.0.0:8080, udp://127.0.0.1:5353 oder unix:///tmp/app.sock. Für TLS/SSL-Verbindungen werden die Kontextoptionen über einen Stream-Kontext (stream_context_create()) übergeben.

Mit dem Parameter $flags lässt sich steuern, ob nur gebunden (STREAM_SERVER_BIND) oder zusätzlich auf Verbindungen gehorcht wird (STREAM_SERVER_LISTEN). Bei UDP-Sockets sollte STREAM_SERVER_BIND ohne STREAM_SERVER_LISTEN verwendet werden, da UDP verbindungslos ist.

Nach erfolgreichem Aufruf können mit stream_socket_accept() eingehende Verbindungen angenommen werden. Die zurückgegebene Ressource sollte nach Gebrauch mit fclose() geschlossen werden.

Parameter

Name Typ Default Beschreibung
$address Pflicht string Die Adresse des Sockets im Format transport://host:port, z. B. tcp://0.0.0.0:8080 oder unix:///var/run/app.sock.
$error_code int null Wird bei einem Fehler mit dem systemspezifischen Fehlercode befüllt (by reference). Bleibt 0, wenn kein Fehler aufgetreten ist.
$error_message string null Wird bei einem Fehler mit der zugehörigen Fehlermeldung als Zeichenkette befüllt (by reference).
$flags int STREAM_SERVER_BIND | STREAM_SERVER_LISTEN Bitmaske aus STREAM_SERVER_BIND und/oder STREAM_SERVER_LISTEN. Für UDP sollte nur STREAM_SERVER_BIND gesetzt werden.
$context resource|null null Optionaler Stream-Kontext, der z. B. SSL-Zertifikat und -Schlüssel für TLS-Server-Sockets enthält. Wird mit stream_context_create() erzeugt.

Rückgabewert

Typ
resource|false
Beschreibung
Bei Erfolg eine Stream-Ressource, die den Server-Socket repräsentiert. Im Fehlerfall wird false zurückgegeben und $error_code sowie $error_message werden befüllt.

Beispiele

Einfacher TCP-Echo-Server

<?php
$address = 'tcp://127.0.0.1:9000';
$server = stream_socket_server($address, $errno, $errstr);

if ($server === false) {
    die("Konnte Socket nicht öffnen: [$errno] $errstr\n");
}

echo "Server lauscht auf $address ...\n";

while ($client = stream_socket_accept($server, 30)) {
    $data = fread($client, 1024);
    echo "Empfangen: $data";
    fwrite($client, "Echo: " . $data);
    fclose($client);
}

fclose($server);
Server lauscht auf tcp://127.0.0.1:9000 ...

TLS-Server-Socket mit Stream-Kontext

<?php
$context = stream_context_create([
    'ssl' => [
        'local_cert'        => '/etc/ssl/certs/server.pem',
        'local_pk'          => '/etc/ssl/private/server.key',
        'allow_self_signed' => true,
        'verify_peer'       => false,
    ],
]);

$server = stream_socket_server(
    'tls://0.0.0.0:4430',
    $errno,
    $errstr,
    STREAM_SERVER_BIND | STREAM_SERVER_LISTEN,
    $context
);

if ($server === false) {
    die("TLS-Server-Fehler [$errno]: $errstr\n");
}

echo "TLS-Server gestartet auf Port 4430\n";

while ($client = stream_socket_accept($server, 60, $peer)) {
    echo "Verbindung von: $peer\n";
    fwrite($client, "Willkommen beim sicheren Server!\r\n");
    fclose($client);
}

fclose($server);
TLS-Server gestartet auf Port 4430

UDP-Socket (nur binden, kein listen)

<?php
$server = stream_socket_server(
    'udp://127.0.0.1:5000',
    $errno,
    $errstr,
    STREAM_SERVER_BIND
);

if ($server === false) {
    die("UDP-Fehler [$errno]: $errstr\n");
}

echo "UDP-Socket bereit auf Port 5000\n";

// Datagramm empfangen
$data = stream_socket_recvfrom($server, 512, 0, $peer);
echo "Paket von $peer: $data\n";

fclose($server);
UDP-Socket bereit auf Port 5000

// Wichtig · Fallstricke

Sicherheit: Binde Server-Sockets niemals unnötigerweise an 0.0.0.0 (alle Schnittstellen), wenn der Dienst nur lokal erreichbar sein soll. Verwende stattdessen 127.0.0.1.

Blockierendes vs. nicht-blockierendes I/O: Standardmäßig ist der Socket blockierend. Mit stream_set_blocking($server, false) kann er in den nicht-blockierenden Modus versetzt werden, was für Event-Loops (z. B. in Kombination mit stream_select()) notwendig ist.

Unix-Domain-Sockets: Bei unix://-Sockets bleibt die Socket-Datei nach Programmende erhalten. Sie sollte im Aufräum-Code explizit mit unlink() gelöscht werden.

Port-Privilegien: Ports unter 1024 erfordern unter Linux/Unix Root-Rechte oder entsprechende Capabilities (CAP_NET_BIND_SERVICE). Für Produktivumgebungen empfiehlt sich ein Reverse-Proxy wie nginx.