(PHP 5 >= 5.5.0, PHP 7, PHP 8)
socket_sendmsg — メッセージを送信する
関数 socket_sendmsg() は、sendmsg()
システムコールを使って、message
で指定したメッセージをソケット socket 経由で送信します。
socketsocket_create()、socket_accept() あるいは socket_create_pair() で作成した Socket クラスのインスタンス。
message以下の要素を含むことができる連想配列。要素はどれも省略でき、 認識できないキーは黙って無視されます。なお、送信時には flags という要素はありません。このキーが現れるのは、 socket_recvmsg() が値を設定する配列だけです。
リモートホストのアドレスを表す配列。キーは、
AF_INET の場合は addr と
port、AF_INET6 の場合は
addr、port、flowinfo
と scope_id、AF_UNIX の場合は
path です。
addr には IP アドレスかホスト名を指定でき、
ホスト名は名前解決されます。オプションの family
キーで、アドレスファミリーを明示的に指定できます。省略した場合は、
socket のアドレスファミリーを使います。
ソケットがサポートしていないアドレスファミリーを指定すると、
呼び出しは失敗します。
送信するデータを格納したバッファのリスト。これらのバッファは、
順番どおりにひとつのメッセージとして送信されます。
配列のキーは無視され、値は文字列に変換されます。
このキー自体がないか空の場合は、データは送信されず、
関数は 0 を返します。
補助データメッセージのリスト。各メッセージは、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 演算子 (|) で連結したものとなります。
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