PHP 8.4.26 Released!

socket_sendmsg

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

socket_sendmsg — メッセージを送信する

説明

function socket_sendmsg(Socket $socket, array $message, int $flags = 0): int|false

関数 socket_sendmsg() は、sendmsg() システムコールを使って、message で指定したメッセージをソケット socket 経由で送信します。

パラメータ

socket

socket_create()、socket_accept() あるいは socket_create_pair() で作成した Socket クラスのインスタンス。

message

以下の要素を含むことができる連想配列。要素はどれも省略でき、 認識できないキーは黙って無視されます。なお、送信時には flags という要素はありません。このキーが現れるのは、 socket_recvmsg() が値を設定する配列だけです。

name

リモートホストのアドレスを表す配列。キーは、 AF_INET の場合は addr と port、AF_INET6 の場合は addr、port、flowinfo と scope_id、AF_UNIX の場合は path です。 addr には IP アドレスかホスト名を指定でき、 ホスト名は名前解決されます。オプションの family キーで、アドレスファミリーを明示的に指定できます。省略した場合は、 socket のアドレスファミリーを使います。 ソケットがサポートしていないアドレスファミリーを指定すると、 呼び出しは失敗します。

iov

送信するデータを格納したバッファのリスト。これらのバッファは、 順番どおりにひとつのメッセージとして送信されます。 配列のキーは無視され、値は文字列に変換されます。 このキー自体がないか空の場合は、データは送信されず、 関数は 0 を返します。

control

補助データメッセージのリスト。各メッセージは、level、 type、data をキーに持つ配列です。サポートされているのは以下の組み合わせだけで、 使えるかどうかはプラットフォームによって異なります。

サポートされている補助データ
level type data
SOL_SOCKET SCM_RIGHTS Socket クラスのインスタンスかストリームリソースを 1 つ以上含むリスト。各要素のファイルディスクリプタが、 受信側のプロセスに送られます。
SOL_SOCKET SCM_CREDENTIALS pid、uid、 gid をキーに持つ配列。 一部のシステムでは、定数名が SCM_CREDS または SCM_CREDS2 になります。
IPPROTO_IPV6 IPV6_PKTINFO addr と ifindex をキーに持つ配列。
IPPROTO_IPV6 IPV6_HOPLIMIT 整数値。
IPPROTO_IPV6 IPV6_TCLASS 整数値。
flags

flags の値は、以下のフラグの任意の組み合わせを ビット OR 演算子 (|) で連結したものとなります。

flags がとりうる値
MSG_OOB OOB(out-of-band: 帯域外)データを送信します。
MSG_EOR レコードの区切りを示します。 送信したデータでレコードが完結します。
MSG_DONTWAIT このフラグを設定すると、通常ならブロックするような場面でも、関数はブロックせずに制御を返します。
MSG_DONTROUTE ルータを使用せず、直接つながっているインターフェイスのみを使用します。

戻り値

送信したバイト数を返します。失敗した場合に false を返します。

変更履歴

バージョン 説明
8.0.0 socket は、Socket クラスのインスタンスになりました。 これより前のバージョンでは、リソース型でした。

例

例1 socket_sendmsg() でメッセージを送信する

<?php
$server = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($server, '127.0.0.1', 1053);

$client = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
$sent = socket_sendmsg($client, [
    'name' => ['addr' => '127.0.0.1', 'port' => 1053],
    'iov'  => ['Hello ', 'world'],
], 0);

echo "sent: $sent\n";

socket_recvfrom($server, $buffer, 64, 0, $from, $port);
echo "received: $buffer\n";
?>

上の例の出力は以下となります。

sent: 11
received: Hello world

例2 UNIX ソケット経由でファイルディスクリプタを渡す

control キーには補助データを格納します。 SCM_RIGHTS を使うと、開いているファイルディスクリプタが UNIX ソケットの相手側のプロセスに渡されます。これは Windows では利用できません。

<?php
socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $pair);
[$sender, $receiver] = $pair;

$file = fopen(__FILE__, 'r');

socket_sendmsg($sender, [
    // 補助データを送るには、1 バイト以上の通常のデータも一緒に送る必要があります。
    'iov'     => ['fd'],
    'control' => [
        ['level' => SOL_SOCKET, 'type' => SCM_RIGHTS, 'data' => [$file]],
    ],
], 0);

$message = [
    'buffer_size' => 16,
    'controllen'  => socket_cmsg_space(SOL_SOCKET, SCM_RIGHTS, 1),
];
socket_recvmsg($receiver, $message, 0);

$received = $message['control'][0]['data'][0];
echo "first line: ", fgets($received);
?>

上の例の出力は以下となります。

first line: <?php

参考

+add a note

User Contributed Notes

There are no user contributed notes for this page.
To Top