Start · Sprachen · PHP · Referenz · socket_recv

socket_recv

Funktion

Empfängt Daten von einem verbundenen Socket und schreibt sie in den Puffer <code>$buf</code>.

seit PHP 4.1.0 Kategorie: http

Signatur

socket_recv(Socket $socket, ?string &$buf, int $len, int $flags): int|false

Beschreibung

socket_recv() liest bis zu $len Bytes vom angegebenen, verbundenen Socket und speichert die empfangenen Daten in der Variablen $buf. Die Funktion ist das Socket-Äquivalent zu fread() für Stream-Ressourcen und eignet sich besonders für die direkte TCP/UDP-Kommunikation auf niedriger Ebene.

Das Verhalten der Funktion wird durch den Parameter $flags gesteuert. Damit lassen sich z. B. OOB-Daten (Out-of-Band) lesen, das Abholen der Daten aus dem Puffer verhindern (MSG_PEEK) oder blockierende Wartezeiten umgehen (MSG_DONTWAIT). Die Flags können per bitweisem ODER kombiniert werden.

Wenn die Verbindung vom Gegenstück getrennt wurde, gibt die Funktion 0 zurück und $buf wird auf einen leeren String gesetzt – dieser Zustand muss im eigenen Code explizit geprüft werden. Bei einem Fehler wird false zurückgegeben; der genaue Fehlercode kann dann mit socket_last_error() abgefragt werden.

Im Gegensatz zu socket_read() erlaubt socket_recv() die Nutzung von Flags und ist damit die flexiblere Wahl für anspruchsvolle Netzwerkanwendungen wie Chat-Server, Protokoll-Implementierungen oder Binärprotokolle.

Parameter

Name Typ Default Beschreibung
$socket Pflicht Socket Ein gültiges Socket-Objekt, das zuvor mit socket_create() erstellt und mit socket_connect() oder socket_accept() verbunden wurde.
$buf Pflicht ?string Referenz auf eine Variable, in die die empfangenen Daten geschrieben werden. Wird bei einem Fehler auf null gesetzt.
$len Pflicht int Maximale Anzahl an Bytes, die aus dem Socket gelesen werden sollen. Es können weniger Bytes empfangen werden, wenn weniger Daten verfügbar sind.
$flags Pflicht int Kombination aus folgenden Konstanten (bitweises ODER): MSG_OOB (Out-of-Band-Daten lesen), MSG_PEEK (Daten lesen ohne aus dem Puffer zu entfernen), MSG_WAITALL (warten bis alle $len Bytes vorliegen), MSG_DONTWAIT (nicht blockieren). Für normales Empfangen kann 0 übergeben werden.

Rückgabewert

Typ
int|false
Beschreibung
Gibt die Anzahl der tatsächlich empfangenen Bytes zurück. Gibt 0 zurück, wenn die Verbindung vom Gegenstück geschlossen wurde. Gibt false zurück, wenn ein Fehler aufgetreten ist; der Fehlercode kann mit socket_last_error() ermittelt werden.

Beispiele

Einfache TCP-Verbindung mit socket_recv()

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

if (!socket_connect($socket, 'example.com', 80)) {
    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";
socket_send($socket, $request, strlen($request), 0);

$response = '';
while (true) {
    $bytesRead = socket_recv($socket, $buf, 2048, 0);
    if ($bytesRead === false) {
        echo 'Fehler beim Empfangen: ' . socket_strerror(socket_last_error($socket));
        break;
    }
    if ($bytesRead === 0) {
        // Verbindung wurde vom Server geschlossen
        break;
    }
    $response .= $buf;
}

socket_close($socket);
echo "Empfangene Bytes: " . strlen($response) . PHP_EOL;
echo substr($response, 0, 200); // Ersten 200 Zeichen ausgeben
Empfangene Bytes: 1234 HTTP/1.1 200 OK Content-Type: text/html; ...

Nicht-blockierendes Empfangen mit MSG_DONTWAIT

<?php
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($server, '127.0.0.1', 9000);
socket_listen($server);

echo "Warte auf Verbindung..." . PHP_EOL;
$client = socket_accept($server);

// Nicht-blockierend lesen: sofortige Rückkehr auch wenn keine Daten vorliegen
$bytesRead = socket_recv($client, $buf, 1024, MSG_DONTWAIT);

if ($bytesRead === false) {
    $error = socket_last_error($client);
    // EAGAIN / EWOULDBLOCK bedeutet: noch keine Daten verfügbar
    echo 'Kein Daten verfügbar oder Fehler: ' . socket_strerror($error) . PHP_EOL;
} elseif ($bytesRead === 0) {
    echo 'Verbindung geschlossen.' . PHP_EOL;
} else {
    echo "Empfangen ($bytesRead Bytes): $buf" . PHP_EOL;
}

socket_close($client);
socket_close($server);
Warte auf Verbindung... Empfangen (13 Bytes): Hallo Server!

// Wichtig · Fallstricke

Verbindungsende prüfen: Ein Rückgabewert von 0 signalisiert, dass die Gegenseite die Verbindung geschlossen hat. Dieser Fall muss explizit behandelt werden – andernfalls läuft die Anwendung in eine Endlosschleife.

Binäre Daten: socket_recv() ist binärsicher. Bei der Verarbeitung von Binärprotokollen (z. B. mit pack()/unpack()) sollte MSG_WAITALL verwendet werden, um sicherzustellen, dass wirklich alle erwarteten Bytes empfangen wurden, bevor das Paket interpretiert wird.

Sicherheit: Die empfangenen Daten stammen aus einem externen Netzwerk und müssen vor der Weiterverarbeitung stets validiert und ggf. escaped werden, um XSS, Injection-Angriffe oder Pufferüberläufe in der Applikationslogik zu verhindern.

PHP 8.0: Ab PHP 8.0 wird der erste Parameter als Socket-Objekt erwartet; in früheren Versionen war es eine Ressource vom Typ resource.