Signatur
Beschreibung
socket_recvfrom() liest bis zu $len Bytes vom angegebenen Socket in den Puffer $buf und speichert gleichzeitig die IP-Adresse (bzw. den Unix-Domain-Socket-Pfad) des Absenders in $name sowie bei UDP/IP den Absender-Port in $port. Dies macht die Funktion besonders nützlich für verbindungslose Protokolle wie UDP, wo jedes Datagramm potenziell von einem anderen Host stammen kann.
Im Gegensatz zu socket_recv() funktioniert socket_recvfrom() auch ohne eine zuvor aufgebaute Verbindung (socket_connect()). Dadurch eignet sie sich ideal für UDP-Server, die Anfragen von beliebigen Clients empfangen und gezielt antworten müssen, ohne eine dauerhafte Verbindung aufrechtzuerhalten.
Der Parameter $flags erlaubt es, das Empfangsverhalten zu steuern. Gängige Werte sind MSG_WAITALL (warte bis alle Bytes angekommen sind), MSG_PEEK (Daten lesen ohne sie aus dem Puffer zu entfernen) und MSG_DONTWAIT (nicht blockierender Empfang). Diese Flags können mit dem bitweisen ODER-Operator kombiniert werden.
Schlägt der Empfang fehl, gibt die Funktion false zurück. Mit socket_last_error() und socket_strerror() lässt sich der genaue Fehlergrund ermitteln. Bei Erfolg wird die Anzahl der tatsächlich empfangenen Bytes zurückgegeben.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $socket Pflicht | Socket | Eine gültige Socket-Ressource bzw. ein Socket-Objekt, das zuvor mit socket_create() erzeugt wurde. |
|
| $buf Pflicht | string | Referenz auf eine Variable, in die die empfangenen Daten geschrieben werden. | |
| $len Pflicht | int | Maximale Anzahl an Bytes, die empfangen werden sollen. Bei UDP sollte dieser Wert die maximale Datagrammgröße nicht überschreiten (typisch: 65535 Bytes). | |
| $flags Pflicht | int | Bitmaske aus Empfangs-Flags wie MSG_WAITALL, MSG_PEEK oder MSG_DONTWAIT. Übergib 0 für Standardverhalten. |
|
| $name Pflicht | string | Referenz auf eine Variable, die nach dem Aufruf die IP-Adresse (IPv4/IPv6) oder den Pfad (Unix-Domain-Socket) des Absenders enthält. | |
| $port | int | null | Referenz auf eine Variable, die den Absender-Port enthält. Nur bei AF_INET- und AF_INET6-Sockets relevant; bei Unix-Domain-Sockets wird dieser Parameter ignoriert. |
Rückgabewert
int zurück. Bei einem Fehler wird false zurückgegeben; der genaue Fehler kann mit socket_last_error() abgefragt werden.Beispiele
Einfacher UDP-Server: Datagramme empfangen und Absender ermitteln
<?php
// UDP-Socket erstellen und an Port 9000 binden
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
if ($socket === false) {
die('socket_create() fehlgeschlagen: ' . socket_strerror(socket_last_error()));
}
if (!socket_bind($socket, '0.0.0.0', 9000)) {
die('socket_bind() fehlgeschlagen: ' . socket_strerror(socket_last_error($socket)));
}
echo "UDP-Server lauscht auf Port 9000 ...\n";
// Auf eingehende Datagramme warten
$buf = '';
$from = '';
$port = 0;
$bytes = socket_recvfrom($socket, $buf, 65535, 0, $from, $port);
if ($bytes === false) {
echo 'Fehler: ' . socket_strerror(socket_last_error($socket)) . "\n";
} else {
echo "Empfangen: {$bytes} Byte(s) von {$from}:{$port}\n";
echo "Inhalt: {$buf}\n";
// Antwort an den Absender schicken
socket_sendto($socket, 'ACK', 3, 0, $from, $port);
}
socket_close($socket);
UDP-Server-Schleife: Mehrere Clients bedienen
<?php
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($socket, '0.0.0.0', 9001);
echo "Warte auf UDP-Pakete auf Port 9001 ...\n";
while (true) {
$buf = '';
$from = '';
$port = 0;
$bytes = socket_recvfrom($socket, $buf, 4096, 0, $from, $port);
if ($bytes === false) {
$errCode = socket_last_error($socket);
echo 'Fehler ' . $errCode . ': ' . socket_strerror($errCode) . "\n";
continue;
}
$ts = date('H:i:s');
$msg = trim($buf);
echo "[{$ts}] {$from}:{$port} → {$msg}\n";
// Echo zurücksenden
$response = strtoupper($msg);
socket_sendto($socket, $response, strlen($response), 0, $from, $port);
if ($msg === 'QUIT') {
echo "Server wird beendet.\n";
break;
}
}
socket_close($socket);
// Wichtig · Fallstricke
Sicherheit: Die empfangenen Daten in $buf stammen aus einer nicht vertrauenswürdigen Quelle. Validiere und sanitisiere den Inhalt immer, bevor er weiterverarbeitet oder ausgegeben wird, um Buffer-Overflows in nachgelagerten Funktionen oder XSS-Angriffe zu vermeiden.
Blockierendes Verhalten: Standardmäßig blockiert socket_recvfrom(), bis Daten eintreffen. Mit socket_set_nonblock() oder dem Flag MSG_DONTWAIT kann der Socket auf nicht-blockierenden Modus umgestellt werden – in diesem Fall gibt die Funktion sofort false zurück, wenn keine Daten vorliegen (Fehlercode EAGAIN/EWOULDBLOCK).
IPv6: Bei AF_INET6-Sockets enthält $name die IPv6-Adresse im Standardformat, z. B. ::1. $port wird analog zu IPv4 befüllt.
PHP 8.0+: Ab PHP 8.0 ist $socket ein Socket-Objekt statt einer Ressource. Der Funktionsaufruf selbst bleibt kompatibel.