Start · Sprachen · PHP · Referenz · socket_write

socket_write

Funktion

Schreibt Daten in einen Socket und gibt die Anzahl der tatsächlich geschriebenen Bytes zurück.

seit PHP 4.1.0 Kategorie: http

Signatur

socket_write(Socket $socket, string $data, int $length = 0): int|false

Beschreibung

socket_write() sendet einen String über einen zuvor mit socket_create() oder socket_accept() erzeugten Socket. Die Funktion eignet sich für TCP-basierte Verbindungen sowie für Unix-Domain-Sockets und ist das Gegenstück zu socket_read().

Der optionale Parameter $length begrenzt die Anzahl der zu schreibenden Bytes. Wird er weggelassen oder auf 0 gesetzt, wird der gesamte übergebene String gesendet. Es ist möglich, dass nicht alle Bytes auf einmal übertragen werden – daher sollte in produktivem Code geprüft werden, ob der Rückgabewert der Länge des gesendeten Strings entspricht, und bei Bedarf in einer Schleife erneut gesendet werden.

Im Fehlerfall gibt die Funktion false zurück. Der genaue Fehlercode kann danach mit socket_last_error() abgerufen und mit socket_strerror() in eine lesbare Meldung umgewandelt werden.

Für nicht-verbindungsorientierte Sockets (UDP) sollte stattdessen socket_sendto() verwendet werden, da dort die Zieladresse explizit angegeben werden muss.

Parameter

Name Typ Default Beschreibung
$socket Pflicht Socket Eine gültige Socket-Instanz, die zuvor mit socket_create(), socket_accept() oder einer ähnlichen Funktion erzeugt wurde.
$data Pflicht string Die zu sendenden Daten als Zeichenkette. Kann beliebige Binärdaten oder Text enthalten.
$length int 0 Maximale Anzahl der zu schreibenden Bytes. Ist der Wert 0 oder wird der Parameter weggelassen, wird die gesamte Länge von $data verwendet.

Rückgabewert

Typ
int|false
Beschreibung
Gibt die Anzahl der erfolgreich geschriebenen Bytes zurück. Im Fehlerfall wird false zurückgegeben. Ein Rückgabewert von 0 ist möglich und bedeutet, dass keine Bytes geschrieben wurden (kein Fehler, aber auch kein Fortschritt).

Beispiele

Einfaches Senden einer HTTP-Anfrage über einen TCP-Socket

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

$result = socket_connect($socket, 'example.com', 80);
if ($result === false) {
    die('socket_connect() fehlgeschlagen: ' . socket_strerror(socket_last_error($socket)));
}

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

if ($written === false) {
    die('socket_write() fehlgeschlagen: ' . socket_strerror(socket_last_error($socket)));
}

echo "Bytes gesendet: $written" . PHP_EOL;

$response = '';
while ($chunk = socket_read($socket, 2048)) {
    $response .= $chunk;
}

echo $response;
socket_close($socket);
Bytes gesendet: 47 (HTTP-Antwort von example.com)

Robustes Senden mit Schleife (bei partiellen Schreibvorgängen)

<?php
function socket_write_all(Socket $socket, string $data): int|false
{
    $total = 0;
    $length = strlen($data);

    while ($total < $length) {
        $written = socket_write($socket, substr($data, $total), $length - $total);
        if ($written === false) {
            return false;
        }
        $total += $written;
    }

    return $total;
}

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '127.0.0.1', 8080);

$message = "Hallo Server, das ist eine lange Nachricht die vollständig gesendet werden soll.";
$bytesSent = socket_write_all($socket, $message);

if ($bytesSent === false) {
    echo 'Fehler beim Senden: ' . socket_strerror(socket_last_error($socket));
} else {
    echo "Vollständig gesendet: $bytesSent Bytes" . PHP_EOL;
}

socket_close($socket);
Vollständig gesendet: 80 Bytes

// Wichtig · Fallstricke

Partielle Schreibvorgänge: socket_write() garantiert nicht, dass alle übergebenen Bytes in einem einzigen Aufruf gesendet werden. Besonders bei großen Datenmengen oder ausgelastetem Netzwerk kann der Rückgabewert kleiner als strlen($data) sein. Für zuverlässige Übertragung sollte eine Schleife (wie im zweiten Beispiel gezeigt) verwendet werden.

Verwechslungsgefahr mit fwrite(): Wer PHP-Streams statt der Low-Level-Socket-Extension verwendet, sollte fwrite() auf einem mit stream_socket_client() erstellten Stream nutzen. socket_write() funktioniert ausschließlich mit Socket-Objekten der sockets-Extension.

Binärsicherheit: Die Funktion ist binärsicher und kann beliebige Bytefolgen senden, also auch Null-Bytes. Der Parameter $length sollte in diesem Fall korrekt gesetzt werden, da PHP-Strings intern keine Null-Terminierung verwenden, aber strlen() korrekt zählt.

Blockierender Modus: Standardmäßig blockiert socket_write(), bis Daten gesendet werden konnten. Im nicht-blockierenden Modus (gesetzt via socket_set_nonblock()) kann die Funktion sofort mit false oder 0 zurückkehren, wenn der Sendepuffer voll ist.