Start · Sprachen · PHP · Referenz · stream_socket_client

stream_socket_client

Funktion

Öffnet eine Internet- oder Unix-Domain-Socket-Verbindung und gibt einen Stream-Ressource-Handle zurück.

seit PHP 5.0.0 Kategorie: io

Signatur

stream_socket_client(string $address, int &$error_code = null, string &$error_message = null, float $timeout = null, int $flags = STREAM_CLIENT_CONNECT, resource $context = null): resource|false

Beschreibung

stream_socket_client() stellt eine Socket-Verbindung zu einem angegebenen Ziel her und gibt eine Stream-Ressource zurück, die mit den üblichen Stream-Funktionen wie fread(), fwrite() und fclose() verwendet werden kann. Die Adresse kann verschiedene Transport-Protokolle nutzen, z. B. tcp://, udp://, ssl://, tls:// oder unix://.

Über den Parameter $flags lässt sich steuern, ob die Verbindung synchron (STREAM_CLIENT_CONNECT), asynchron (STREAM_CLIENT_ASYNC_CONNECT) oder persistent (STREAM_CLIENT_PERSISTENT) aufgebaut wird. Persistente Verbindungen werden über mehrere Requests hinweg wiederverwendet und verbessern die Performance bei häufigen Verbindungen zum gleichen Ziel.

Schlägt der Verbindungsaufbau fehl, wird false zurückgegeben. Die Fehlerursache kann dann über die per Referenz übergebenen Parameter $error_code und $error_message ausgelesen werden. Ein optionaler Stream-Kontext ($context) erlaubt die feingranulare Steuerung von TLS-Optionen, Proxy-Einstellungen und mehr.

Typische Einsatzgebiete sind das direkte Ansprechen von TCP/UDP-Diensten, die Implementierung von HTTP-Clients ohne cURL, der Aufbau verschlüsselter TLS-Verbindungen sowie die Kommunikation über Unix-Domain-Sockets bei lokalen Diensten.

Parameter

Name Typ Default Beschreibung
$address Pflicht string Die Zieladresse im Format transport://host:port, z. B. tcp://example.com:80, ssl://example.com:443 oder unix:///var/run/service.sock.
$error_code int null Wird per Referenz übergeben und enthält nach einem Fehler den systemspezifischen Fehlercode (entspricht dem POSIX-Fehler).
$error_message string null Wird per Referenz übergeben und enthält nach einem Fehler eine lesbare Fehlermeldung als Zeichenkette.
$timeout float ini_get("default_socket_timeout") Timeout in Sekunden für den Verbindungsaufbau. Wird kein Wert übergeben, gilt der PHP-INI-Wert default_socket_timeout.
$flags int STREAM_CLIENT_CONNECT Bitmaske aus Verbindungsflags: STREAM_CLIENT_CONNECT (synchron), STREAM_CLIENT_ASYNC_CONNECT (asynchron) oder STREAM_CLIENT_PERSISTENT (persistente Verbindung).
$context resource null Ein mit stream_context_create() erzeugter Stream-Kontext, über den z. B. TLS-Zertifikate, Proxy-Server oder weitere Optionen konfiguriert werden können.

Rückgabewert

Typ
resource|false
Beschreibung
Gibt eine Stream-Ressource zurück, die mit den Standard-Stream-Funktionen verwendet werden kann. Bei einem Fehler wird false zurückgegeben und die Fehlerinformationen stehen in $error_code und $error_message zur Verfügung.

Beispiele

Einfache TCP-Verbindung zu einem HTTP-Server

<?php
$errno = 0;
$errstr = '';

$socket = stream_socket_client(
    'tcp://example.com:80',
    $errno,
    $errstr,
    5.0
);

if ($socket === false) {
    echo "Verbindungsfehler [{$errno}]: {$errstr}\n";
    exit(1);
}

// HTTP-Anfrage senden
fwrite($socket, "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n");

// Antwort lesen
$response = '';
while (!feof($socket)) {
    $response .= fread($socket, 8192);
}

fclose($socket);

// Ersten 200 Zeichen der Antwort ausgeben
echo substr($response, 0, 200);
HTTP/1.0 200 OK Content-Type: text/html; charset=UTF-8 ...

Verschlüsselte TLS-Verbindung mit Kontext-Optionen

<?php
$context = stream_context_create([
    'ssl' => [
        'verify_peer'       => true,
        'verify_peer_name'  => true,
        'cafile'            => '/etc/ssl/certs/ca-certificates.crt',
        'SNI_enabled'       => true,
    ],
]);

$errno = 0;
$errstr = '';

$socket = stream_socket_client(
    'tls://example.com:443',
    $errno,
    $errstr,
    10.0,
    STREAM_CLIENT_CONNECT,
    $context
);

if ($socket === false) {
    echo "TLS-Verbindungsfehler [{$errno}]: {$errstr}\n";
    exit(1);
}

fwrite($socket, "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n");

$response = stream_get_contents($socket);
fclose($socket);

echo "Statuszeile: " . strtok($response, "\r\n") . "\n";
Statuszeile: HTTP/1.1 200 OK

Persistente Verbindung für Wiederverwendung

<?php
function getSocket(string $host, int $port): resource
{
    $errno = 0;
    $errstr = '';

    $socket = stream_socket_client(
        "tcp://{$host}:{$port}",
        $errno,
        $errstr,
        5.0,
        STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT
    );

    if ($socket === false) {
        throw new RuntimeException("Verbindung fehlgeschlagen [{$errno}]: {$errstr}");
    }

    return $socket;
}

// Persistente Verbindung – beim zweiten Aufruf wird die bestehende Verbindung wiederverwendet
$sock1 = getSocket('127.0.0.1', 6379);
$sock2 = getSocket('127.0.0.1', 6379);

var_dump($sock1 === $sock2); // true bei persistenter Verbindung
fclose($sock1);
bool(true)

// Wichtig · Fallstricke

Sicherheit: Bei TLS-Verbindungen sollte verify_peer und verify_peer_name im Stream-Kontext stets auf true gesetzt sein, da PHP sie standardmäßig aktiviert. Das Deaktivieren dieser Optionen macht die Verbindung anfällig für Man-in-the-Middle-Angriffe.

Timeout-Verhalten: Der $timeout-Parameter gilt nur für den Verbindungsaufbau, nicht für nachfolgende Lese-/Schreiboperationen. Für den Datentransfer-Timeout muss stream_set_timeout() nach dem Verbindungsaufbau aufgerufen werden.

Nicht-blockierender Modus: Mit stream_set_blocking($socket, false) kann der Stream in den nicht-blockierenden Modus versetzt werden, was bei asynchronen Szenarien oder der Überwachung mehrerer Sockets mit stream_select() nützlich ist.

Persistente Verbindungen: Persistente Verbindungen (STREAM_CLIENT_PERSISTENT) bleiben nach fclose() intern erhalten und werden beim nächsten Aufruf mit derselben Adresse wiederverwendet. Dies kann zu unerwartetem Verhalten führen, wenn der entfernte Server die Verbindung getrennt hat.