Start · Sprachen · PHP · Referenz · stream_socket_pair

stream_socket_pair

Funktion

Erzeugt ein Paar verbundener, gleichartiger Socket-Streams für die bidirektionale Interprozesskommunikation.

seit PHP 5.1.0 Kategorie: io

Signatur

stream_socket_pair(int $domain, int $type, int $protocol): array|false

Beschreibung

stream_socket_pair() erstellt zwei miteinander verbundene Socket-Streams, die als vollständiges Kommunikationspaar fungieren. Was in den einen Stream geschrieben wird, kann aus dem anderen gelesen werden – und umgekehrt. Dies ist typisch für Unix-Domain-Sockets (auch als socketpair bekannt).

Die Funktion wird häufig eingesetzt, wenn ein Elternprozess mit einem Kind-Prozess kommunizieren soll, der via pcntl_fork() erzeugt wurde. Jeder Prozess schließt dabei den für ihn nicht benötigten Ende des Paares und verwendet das verbleibende für die Kommunikation.

Der Parameter domain gibt die Protokollfamilie an (z. B. STREAM_PF_UNIX für Unix-Domain-Sockets), type beschreibt den Socket-Typ (z. B. STREAM_SOCK_STREAM für zuverlässige Byte-Streams oder STREAM_SOCK_DGRAM für Datagramme) und protocol legt das Transportprotokoll fest (z. B. STREAM_IPPROTO_IP oder 0 für den Standard).

Zu beachten ist, dass diese Funktion auf Windows-Systemen nicht verfügbar ist, da Windows keine nativen Unix-Domain-Socket-Paare unterstützt. Sie eignet sich daher ausschließlich für POSIX-kompatible Betriebssysteme (Linux, macOS, BSD usw.).

Parameter

Name Typ Default Beschreibung
$domain Pflicht int Die Protokollfamilie des Sockets, z. B. STREAM_PF_UNIX für Unix-Domain-Sockets oder STREAM_PF_INET für IPv4. Auf den meisten Systemen wird STREAM_PF_UNIX verwendet.
$type Pflicht int Der Socket-Typ, z. B. STREAM_SOCK_STREAM für einen zuverlässigen, verbindungsorientierten Byte-Stream oder STREAM_SOCK_DGRAM für verbindungslose Datagramme.
$protocol Pflicht int Das zu verwendende Transportprotokoll, z. B. STREAM_IPPROTO_TCP oder 0 (automatische Auswahl). Für Unix-Domain-Sockets wird in der Regel 0 übergeben.

Rückgabewert

Typ
array|false
Beschreibung
Gibt bei Erfolg ein indiziertes Array mit genau zwei Stream-Ressourcen zurück: [0] und [1]. Bei einem Fehler wird false zurückgegeben.

Beispiele

Einfache bidirektionale Kommunikation zwischen zwei Streams

<?php
// Socket-Paar erstellen
$pair = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0);

if ($pair === false) {
    die('Konnte kein Socket-Paar erstellen.');
}

[$socket1, $socket2] = $pair;

// Nachricht über socket1 senden
fwrite($socket1, 'Hallo von Socket 1!');

// Nachricht aus socket2 empfangen
$message = fread($socket2, 1024);
echo $message . PHP_EOL;

// Antwort zurücksenden
fwrite($socket2, 'Antwort von Socket 2!');
$reply = fread($socket1, 1024);
echo $reply . PHP_EOL;

fclose($socket1);
fclose($socket2);
Hallo von Socket 1! Antwort von Socket 2!

Interprozesskommunikation via pcntl_fork()

<?php
if (!function_exists('pcntl_fork')) {
    die('pcntl nicht verfügbar.');
}

$pair = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0);
if ($pair === false) {
    die('Socket-Paar konnte nicht erstellt werden.');
}

$pid = pcntl_fork();

if ($pid === -1) {
    die('Fork fehlgeschlagen.');
} elseif ($pid === 0) {
    // Kind-Prozess: verwendet socket[1]
    fclose($pair[0]);
    $data = fread($pair[1], 1024);
    echo "Kind empfangen: $data" . PHP_EOL;
    fwrite($pair[1], 'Hallo zurück, Eltern!');
    fclose($pair[1]);
    exit(0);
} else {
    // Eltern-Prozess: verwendet socket[0]
    fclose($pair[1]);
    fwrite($pair[0], 'Hallo, Kind!');
    // Kurz warten, damit das Kind antwortet
    usleep(50000);
    $reply = fread($pair[0], 1024);
    echo "Eltern empfangen: $reply" . PHP_EOL;
    fclose($pair[0]);
    pcntl_wait($status);
}
Kind empfangen: Hallo, Kind! Eltern empfangen: Hallo zurück, Eltern!

// Wichtig · Fallstricke

Windows-Inkompatibilität: stream_socket_pair() ist auf Windows-Betriebssystemen nicht verfügbar. Wer plattformübergreifenden Code schreiben möchte, muss auf Alternativen wie stream_socket_server()/stream_socket_client() mit TCP-Loopback ausweichen.

Ressourcen schließen: In einer Fork-Umgebung ist es wichtig, den jeweils nicht benötigten Stream-Endpunkt im entsprechenden Prozess sofort mit fclose() zu schließen, um Deadlocks und unerwartetes Blockieren beim Lesen zu vermeiden.

Blockierendes I/O: Standardmäßig sind die zurückgegebenen Streams blockierend. Mit stream_set_blocking() kann auf nicht-blockierenden Modus umgestellt werden, falls asynchrones Lesen/Schreiben benötigt wird.