Signatur
Beschreibung
socket_cmsg_space() ermittelt die Anzahl der Bytes, die für einen Kontrollnachrichten-Puffer (Control Message, ancillary data) benötigt werden. Solche Kontrollnachrichten werden beim Senden und Empfangen über Sockets verwendet, etwa um Dateideskriptoren über Unix-Domain-Sockets zu übergeben oder IP-spezifische Optionen (z. B. TTL, Absenderadresse) mitzuliefern.
Die Funktion berücksichtigt systeminterne Alignment- und Padding-Anforderungen und liefert die exakte Puffergröße, die für die Übergabe an socket_recvmsg() oder socket_sendmsg() benötigt wird. Ohne korrekt dimensionierten Puffer können Kontrollnachrichten abgeschnitten oder nicht korrekt übertragen werden.
Typische Anwendungsfälle sind das Weiterreichen von Dateideskriptoren zwischen Prozessen (SCM_RIGHTS), das Abrufen von Zeitstempeln (SO_TIMESTAMP) sowie das Setzen oder Lesen von IP-Optionen wie IP_PKTINFO. Der Parameter n gibt bei Kontrollnachrichten mit variabler Länge (z. B. mehrere Dateideskriptoren) die Anzahl der Elemente an.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $level Pflicht | int | Das Protokoll-Level der Kontrollnachricht, z. B. SOL_SOCKET, IPPROTO_IP oder IPPROTO_IPV6. |
|
| $type Pflicht | int | Der Typ der Kontrollnachricht innerhalb des angegebenen Levels, z. B. SCM_RIGHTS (Dateideskriptoren), SCM_CREDENTIALS oder IP_PKTINFO. |
|
| $n | int | 0 | Die Anzahl der Datenobjekte für Kontrollnachrichten mit variabler Länge. Bei SCM_RIGHTS beispielsweise die Anzahl der zu übertragenden Dateideskriptoren. Standard ist 0. |
Rückgabewert
int zurück. Bei einem Fehler (z. B. ungültige Parameter oder nicht unterstützte Kombination) wird false zurückgegeben.Beispiele
Puffergröße für SCM_RIGHTS (Dateideskriptor-Übergabe) berechnen
<?php
// Berechne Puffergröße für die Übertragung von 2 Dateideskriptoren
// über einen Unix-Domain-Socket
$level = SOL_SOCKET;
$type = SCM_RIGHTS;
$anzahlFds = 2;
$pufferGroesse = socket_cmsg_space($level, $type, $anzahlFds);
if ($pufferGroesse === false) {
echo "Fehler beim Berechnen der Puffergröße.\n";
} else {
echo "Benötigte Puffergröße für {$anzahlFds} Dateideskriptoren: {$pufferGroesse} Bytes\n";
}
Puffergröße für IP_PKTINFO beim Empfang mit socket_recvmsg()
<?php
// Unix-Domain-UDP-Socket erstellen und Puffergröße für IP_PKTINFO ermitteln
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($sock, '0.0.0.0', 12345);
// socket_set_option für IP_PKTINFO aktivieren
socket_set_option($sock, IPPROTO_IP, IP_PKTINFO, 1);
// Benötigte Puffergröße für Kontrollnachricht ermitteln
$cmsgSpace = socket_cmsg_space(IPPROTO_IP, IP_PKTINFO);
echo "CMSG-Puffergröße für IP_PKTINFO: {$cmsgSpace} Bytes\n";
// Puffer für socket_recvmsg() vorbereiten
$data = '';
$from = '';
$port = 0;
$message = [
'name' => ['family' => AF_INET, 'addr' => '', 'port' => 0],
'iov' => [['buffer' => &$data, 'length' => 1024]],
'control' => [['level' => IPPROTO_IP, 'type' => IP_PKTINFO, 'data' => '']],
'controllen' => $cmsgSpace,
'flags' => 0,
];
// socket_recvmsg($sock, $message); // würde hier blockieren
socket_close($sock);
// Wichtig · Fallstricke
Plattformabhängigkeit: Die zurückgegebene Puffergröße kann je nach Betriebssystem und CPU-Architektur (32-Bit vs. 64-Bit) unterschiedlich ausfallen, da das interne Padding und Alignment variiert. Die Ausgabewerte im Beispiel sind daher exemplarisch.
Verfügbarkeit: socket_cmsg_space() ist nur verfügbar, wenn PHP mit Socket-Unterstützung (--enable-sockets) kompiliert wurde und das verwendete Betriebssystem POSIX-konforme Ancillary-Data-Unterstützung bietet. Unter Windows ist diese Funktion in der Regel nicht verfügbar.
Zu kleine Puffer: Wird ein zu kleiner Puffer bei socket_recvmsg() angegeben, werden Kontrollnachrichten stillschweigend abgeschnitten (Flag MSG_CTRUNC). Daher sollte socket_cmsg_space() immer zur Dimensionierung verwendet werden.