这里只有两点说明
- 在 UNIX 上,如果设置了 SO_DEBUG,则 php 程序需要有效的用户 ID 为 0。
- 在套接字上激活 SO_OOBINLINE 等效于为与该套接字一起使用的每个接收函数传递 MSG_OOB 标志(例如:socket_recv、socket_recvfrom)。
(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)
socket_get_option — 获取套接字的套接字选项
socket_get_option() 函数检索指定 socket
的由 option
参数指定的选项的值。
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 |
报告如果存在数据, 如果 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 |
加入多播组。 |
array,键为 "group" ,指定包含 IPv4 或 IPv6 多播地址的 string,以及 "interface" ,指定接口号(类型 int)或包含接口名称(例如 "eth0" )的 string 。0 可以指定为指示应使用路由规则选择接口。(只能在 socket_set_option() 中使用) |
MCAST_LEAVE_GROUP |
离开多播组。 |
array。有关详细信息,请参阅 MCAST_JOIN_GROUP 。(只能在 socket_set_option() 中使用) |
MCAST_BLOCK_SOURCE |
阻止来自特定源到特定多播组的数据包,该多播组必须已先前加入。 |
array,与 MCAST_JOIN_GROUP 具有相同的键,还有一个额外的键 source ,它映射到一个 string,指定要阻止的源的 IPv4 或 IPv6 地址。(只能在 socket_set_option() 中使用) |
MCAST_UNBLOCK_SOURCE |
取消阻止(再次开始接收)来自特定源地址到特定多播组的数据包,该多播组必须已先前加入。 |
array,格式与 MCAST_BLOCK_SOURCE 相同。(只能在 socket_set_option() 中使用) |
MCAST_JOIN_SOURCE_GROUP |
接收目标为特定多播组且源地址与特定值匹配的数据包。 |
array,格式与 MCAST_BLOCK_SOURCE 相同。(只能在 socket_set_option() 中使用) |
MCAST_LEAVE_SOURCE_GROUP |
停止接收目标为特定多播组且源地址与特定值匹配的数据包。 |
array,格式与 MCAST_BLOCK_SOURCE 相同。(只能在 socket_set_option() 中使用) |
IP_MULTICAST_IF |
IPv4 多播数据包的出站接口。 | 指定接口号的 int 或包含接口名称(例如 eth0 )的 string。值 0 可用于指示应在接口选择中使用路由表。socket_get_option() 函数返回接口索引。请注意,与 C API 不同,此选项不采用 IP 地址。这消除了 IP_MULTICAST_IF 和 IPV6_MULTICAST_IF 之间的接口差异。 |
IPV6_MULTICAST_IF |
IPv6 多播数据包的出站接口。 | 与 IP_MULTICAST_IF 相同。 |
IP_MULTICAST_LOOP |
IPv4 数据包的多播环回策略启用或禁用已加入的传出多播的环回。但是,其效果在 Unix 和 Windows 系统上的不同,前者作用于接收路径,而后者作用于发送路径。 |
int (值为 0 或 1 )。对于 socket_set_option() 函数,任何值都会被接受,并根据 PHP 的通常规则转换为布尔值。 |
IPV6_MULTICAST_LOOP |
与 IP_MULTICAST_LOOP 类似,但用于 IPv6。 |
int。参见 IP_MULTICAST_LOOP 。 |
IP_MULTICAST_TTL |
传出 IPv4 多播数据包的生存时间 (TTL)。这应该是一个介于 0(不出接口)和 255 之间的数值。默认值为 1(仅到达本地网络)。 | int,介于 0 和 255 之间。 |
IPV6_MULTICAST_HOPS |
与 IP_MULTICAST_TTL 类似,但用于 IPv6 数据包。也接受值 -1,表示应使用路由默认值。 |
int,介于 -1 和 255 之间。 |
SO_MARK |
在 Linux 上为数据包过滤目的设置套接字标识符。 | int |
SO_ACCEPTFILTER |
在监听套接字上添加接受过滤器 (FreeBSD/NetBSD)。在 FreeBSD 上需要预先加载接受过滤器内核模块(例如 accf_http)。 | string 过滤器的名称(最大长度为 15)。 |
SO_USER_COOKIE |
在 FreeBSD 上为数据包过滤目的设置套接字标识符。 | int |
SO_RTABLE |
在 OpenBSD 上为数据包过滤目的设置套接字标识符。 | int |
SO_DONTTRUNC |
保留未读取的数据。 | int |
SO_WANTMORE |
当有更多数据准备好时发出提示。 | int |
TCP_DEFER_ACCEPT |
在数据准备好之前不要通知监听套接字。 | int |
SO_INCOMING_CPU |
获取/设置套接字的 CPU 亲缘性。 | int |
SO_MEMINFO |
获取套接字的所有内存信息。 | int |
SO_BPF_EXTENSIONS |
获取内核支持的附加到套接字的 BPF 扩展。 | int |
SO_SETFIB |
设置套接字的路由表 (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
。
示例 #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));
?>
这里只有两点说明
- 在 UNIX 上,如果设置了 SO_DEBUG,则 php 程序需要有效的用户 ID 为 0。
- 在套接字上激活 SO_OOBINLINE 等效于为与该套接字一起使用的每个接收函数传递 MSG_OOB 标志(例如:socket_recv、socket_recvfrom)。
如果使用 Unix 套接字,并且想要使用 SO_PEERCRED,则可以使用数字 17 作为 optname(以及 SOL_SOCKET 作为级别)。将返回连接进程的 PID。
我正在尝试使用此选项来使用具有相同主机名和相同端口(IRC)的多个套接字连接。但是为此需要的套接字函数是 SO_REUSEPORT。
尽管大多数 Linux 发行版尚未在其发行版中正式实现。
但是对于 Debian,可以安装一个补丁来使其工作
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c617f398edd4db2b8567a28e899a88f8f574798d
它有一些工作要做,但在一段时间后我成功运行了它(Debian 新手),也许其他人也面临着和我一样的问题。
要在专用接口上接收 UDP DHCP 数据包,必须使用未公开的选项 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;
}
}
?>