PHP 8.4.1 Released!

socket_get_option

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

socket_get_optionソケットのオプションを取得する

説明

socket_get_option(Socket $socket, int $level, int $option): array|int|false

socket_get_option() 関数は、ソケット socket のオプション option の値を取得します。socket_get_option() は、失敗した場合に false を返します。

パラメータ

socket

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

level

level パラメータは、オプションのプロトコルレベルを指定します。 例えば、オプションをソケットレベルで取得するには level パラメータに SOL_SOCKET を指定します。 TCP のようなそれ以外のレベルの場合、そのレベルのプロトコル番号を指定します。 プロトコル番号は getprotobyname() 関数を使用して取得可能です。

option
使用可能なソケットオプション
オプション 説明
SO_DEBUG デバッグ情報を記録するかどうかを報告します。 int
SO_BROADCAST ブロードキャストメッセージの送信がサポートされているかどうかを報告します。 int
SO_REUSEADDR ローカルアドレスが再利用可能かどうかを報告します。 int
SO_REUSEPORT ローカルポートが再利用可能かどうかを報告します。 int
SO_KEEPALIVE 定期的なメッセージの送信によって接続がアクティブになっているかどうかを報告します。 もしソケットがこれらのメッセージに応答できなかった場合、 接続は崩壊し、ソケットへの書き込みを行うと SIGPIPE シグナルを受け取ります。 int
SO_LINGER

データがまだ残っているうちに socket_close() をコールした場合に、socket を残存させるかどうかを報告します。 デフォルトでは、ソケットが閉じられる際には未送信のデータをすべて送信しようとします。 接続ベースのソケットでは、 socket_close() は接続先がデータを認識するまで閉じるのを待ちます。

l_onoff が非ゼロで l_linger がゼロの場合は、 その時点で未送信のデータはすべて破棄されます。 接続ベースのソケットの場合、接続先には RST (リセット) を送信します。

一方 l_onoff が非ゼロで l_linger も非ゼロの場合は、 socket_close() は 全データを送信し終えるか l_linger で指定した時間が経過するまで処理をブロックします。 ソケットが非ブロックモードの場合は、 socket_close() は失敗してエラーを返します。

array。配列に含まれるキーは l_onoff および l_linger のふたつ。
SO_OOBINLINE socket が帯域外のデータをインラインに残し続けるかを報告します。 int
SO_SNDBUF 送信バッファのサイズを報告します。 int
SO_RCVBUF 受信バッファのサイズを報告します。 int
SO_ERROR エラーステータスに関する情報を報告し、それをクリアします。 int (socket_set_option() で設定することはできません)
SO_TYPE socket の型 (たとえば SOCK_STREAM) を報告します。 int (socket_set_option() で設定することはできません)
SO_DONTROUTE 送信メッセージがルータを越えるかどうかを報告します。 int
SO_RCVLOWAT socket の入力操作を行う際の最小バイト数を報告します。 int
SO_RCVTIMEO 入力操作のタイムアウト値を報告します。 array。配列に含まれるキーはふたつ。 sec はタイムアウトの秒単位の部分で、 usec はタイムアウトのマイクロ秒位の部分。
SO_SNDTIMEO 出力関数がフロー制御のためにブロックするタイムアウト値を報告します。 array。配列に含まれるキーはふたつ。 sec はタイムアウトの秒単位の部分で、 usec はタイムアウトのマイクロ秒位の部分。
SO_SNDLOWAT socket の出力操作を行う際の最小バイト数を報告します。 int
TCP_NODELAY Nagle TCP アルゴリズムが無効になっているかどうかを報告します。 int
MCAST_JOIN_GROUP マルチキャストグループに参加します。 二つのキー "group""interface" を含む配列。"group" には IPv4 あるいは IPv6 のマルチキャストアドレスを文字列で指定します。 "interface" には、インターフェイス番号 (整数値) あるいは "eth0" などのインターフェイス名 (文字列) を指定します。 0 を指定すると、ルーティングテーブルを使ってインターフェイスを選択します (socket_set_option() でのみ利用可能)。
MCAST_LEAVE_GROUP マルチキャストグループから離れます。 配列。詳細は MCAST_JOIN_GROUP を参照ください (socket_set_option() でのみ利用可能)。
MCAST_BLOCK_SOURCE 特定のソースから、そのマルチキャストグループにやってくるパケットをブロックします。 そのマルチキャストグループに事前に参加しておく必要があります。 MCAST_JOIN_GROUP と同じキーを含み、さらに追加でもうひとつのキーを含む配列。 追加のキーは source で、 ブロック対象となるソースの IPv4 アドレスあるいは IPv6 アドレスを文字列で指定します (socket_set_option() でのみ利用可能)。
MCAST_UNBLOCK_SOURCE 特定のソースから、そのマルチキャストグループにやってくるパケットのブロックを解除 (そして、受信を再開) します。 そのマルチキャストグループに事前に参加しておく必要があります。 MCAST_BLOCK_SOURCE と同じ形式の配列 (socket_set_option() でのみ利用可能)。
MCAST_JOIN_SOURCE_GROUP 特定の値にマッチするソースアドレスからそのマルチキャストグループにやってきたパケットを受信します。 MCAST_BLOCK_SOURCE と同じ形式の配列 (socket_set_option() でのみ利用可能)。
MCAST_LEAVE_SOURCE_GROUP 特定の値にマッチするソースアドレスからそのマルチキャストグループにやってきたパケットの受信を停止します。 MCAST_BLOCK_SOURCE と同じ形式の配列 (socket_set_option() でのみ利用可能)。
IP_MULTICAST_IF IPv4 マルチキャストパケットの送信インターフェイス。 インターフェイス番号を表す整数値か、インターフェイス名を表す eth0 のような文字列。 0 を指定すると、ルーティングテーブルを使ってインターフェイスを選択します。 socket_get_option() 関数の戻り値は、インターフェイスのインデックスとなります。 注意すべき点は、C の API とは違ってこのオプションには IP アドレスを渡せないということです。 そのため、 IP_MULTICAST_IFIPV6_MULTICAST_IF のインターフェイスの相違はなくなります。
IPV6_MULTICAST_IF IPv6 マルチキャストパケットの送信インターフェイス。 IP_MULTICAST_IF と同じ。
IP_MULTICAST_LOOP IPv4 パケットのマルチキャストループバックポリシー。 これを有効にすると、以前に参加したグループに、 マルチキャストのデータをループバックさせることができます。 このオプションの効果は、unix で有効にするか Windows で有効にするかで異なります。 前者は受信先のパスに影響するのに対し、 後者では送信元のパスに影響します。 整数値 (0 あるいは 1)。socket_set_option() では任意の値を受け付けますが、通常の PHP のルールに従ってそれを boolean 値に変換します。
IPV6_MULTICAST_LOOP IP_MULTICAST_LOOP の IPv6 版。 整数値。IP_MULTICAST_LOOP を参照ください。
IP_MULTICAST_TTL IPv4 送信パケットの有効期間。0 (このインターフェイスから離れない) から 255 までの値を指定しなければなりません。デフォルトは 1 (ローカルネットワークにだけ到達する) です。 0 から 255 までの整数値。
IPV6_MULTICAST_HOPS IP_MULTICAST_TTL の IPv6 版。 値として -1 を指定することもでき、これはデフォルトのルートを使うことを意味します。 -1 から 255 までの整数値。
SO_MARK Linux でパケットフィルタを行う目的で、 ソケットの識別子を設定します。 int
SO_ACCEPTFILTER listen しているソケットに対し、accept filter を追加します (FreeBSD/NetBSD)。 accept filter カーネルモジュールは、FreeBSD では前もってロードしておく必要があります (e.g. accf_http)。 フィルタの名前を示す文字列 (最大15文字)
SO_USER_COOKIE FreeBSD でパケットフィルタを行う目的で、 ソケットの識別子を設定します。 int
SO_RTABLE OpenBSD でパケットフィルタを行う目的で、 ソケットの識別子を設定します。 int
SO_DONTTRUNC 未読のデータを保持します。 int
SO_WANTMORE さらにデータが読み取れる時にヒントを与えます。 int
TCP_DEFER_ACCEPT データが利用可能になるまでソケットに通知しません。 int
SO_INCOMING_CPU ソケットの CPU affinity の情報を取得/設定します。 int
SO_MEMINFO ソケットの meminfo を全て取得します。 int
SO_BPF_EXTENSIONS ソケットにアタッチするための、 kernel がサポートしている BPF 拡張を取得します。 int
SO_SETFIB ソケットの route table (FIB) を設定します(FreeBSD のみ) int
SOL_FILTER ソケットの属性をフィルタします(Solaris/Illumos のみ) int
TCP_KEEPCNT 接続を切断する前に、TCP が送信すべき keepalive プローブの最大数を設定します int
TCP_KEEPIDLE 接続がアイドル状態である必要がある、時間を設定します int
TCP_KEEPINTVL 個別の keepalive プローブを送信する間隔を設定します int
TCP_KEEPALIVE 接続がアイドル状態である必要がある、時間を設定します(macOS のみ) int
TCP_NOTSENT_LOWAT ソケットストリームの書き込みキュー中の、未送信のデータ数を制限します(Linuxのみ) int

戻り値

指定したオプションの値を返します。 失敗した場合に false を返します

変更履歴

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

例1 socket_get_option() の例

<?php
$socket
= socket_create_listen(1223);

$linger = array('l_linger' => 1, 'l_onoff' => 1);
socket_set_option($socket, SOL_SOCKET, SO_LINGER, $linger);

var_dump(socket_get_option($socket, SOL_SOCKET, SO_REUSEADDR));
?>

参考

add a note

User Contributed Notes 4 notes

up
5
Chad Lavoie
13 years ago
If using Unix Sockets, and you want to use SO_PEERCRED, you can use the number 17 for the optname (and SOL_SOCKET for the level). The PID of the connecting process will be returned.
up
3
recycling dot sp dot am at gmail dot com
14 years ago
Just 2 notes here:
- On UNIX, If SO_DEBUG is set, the php program needs an effective user id of 0.
- activating SO_OOBINLINE on a socket is equivalent to passing MSG_OOB flag to each recieving functions used with that socket (eg: socket_recv, socket_recvfrom).
up
1
prennings at gmail dot com
10 years ago
I was playing around with this option to use multiply socket connections with same hostname and same port (IRC). However the socket function needed for this is SO_REUSEPORT.

Though the majority of linux distro's does not have that yet officially implented in there distro's.

However for debian there is an patch that can be installed to get it working:

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c617f398edd4db2b8567a28e899a88f8f574798d

it has some work but I got it working after a while (Noobie in debian) maybe some other people are facing the same problem as I was.
up
0
skydiablo at gmx dot net
2 years ago
to receive UDP DHCP packets on a dedicated interface, you have to use the undocumented option SO_BINDTODEVICE:

<?php
$socket
= socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);

socket_set_option($socket, SOL_SOCKET, SO_BINDTODEVICE, 'eth1');
socket_set_option($socket, SOL_SOCKET, SO_BROADCAST, 1);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
socket_set_option($socket, SOL_SOCKET, SO_REUSEPORT, 1);

socket_bind($socket, '255.255.255.255', 67);
while (
1) {
if (
$src = @socket_recv($socket, $data, 9999, 0)) {
echo
$data . PHP_EOL;
}
}
?>
To Top