Start · Sprachen · PHP · Referenz · socket_cmsg_space

socket_cmsg_space

Funktion

Berechnet die benötigte Puffergröße für eine Kontrollnachricht (ancillary data) basierend auf Protokollebene, Typ und optionaler Datenmenge.

seit PHP 5.5.0 Kategorie: http

Signatur

socket_cmsg_space(int $level, int $type, int $n = 0): int|false

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

Typ
int|false
Beschreibung
Gibt die benötigte Puffergröße in Bytes als 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";
}
Benötigte Puffergröße für 2 Dateideskriptoren: 16 Bytes

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);
CMSG-Puffergröße für IP_PKTINFO: 28 Bytes

// 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.