PHP Conference Japan 2024

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

使用 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

报告如果存在数据,socketsocket_close() 时是否会保持连接。默认情况下,当套接字关闭时,它会尝试发送所有未发送的数据。对于面向连接的套接字,socket_close() 将等待其对端确认数据。

如果 l_onoff 非零且 l_linger 为零,则所有未发送的数据将被丢弃,并且在面向连接的套接字的情况下向对端发送 RST(重置)。

另一方面,如果 l_onoff 非零且 l_linger 非零,则 socket_close() 将阻塞,直到所有数据发送完毕或 l_linger 中指定的时间过去。如果套接字是非阻塞的,则 socket_close() 将失败并返回错误。

array。该数组将包含两个键:l_onoffl_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")的 string0 可以指定为指示应使用路由规则选择接口。(只能在 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_IFIPV6_MULTICAST_IF 之间的接口差异。
IPV6_MULTICAST_IF IPv6 多播数据包的出站接口。 IP_MULTICAST_IF 相同。
IP_MULTICAST_LOOP IPv4 数据包的多播环回策略启用或禁用已加入的传出多播的环回。但是,其效果在 Unix 和 Windows 系统上的不同,前者作用于接收路径,而后者作用于发送路径。 int (值为 01)。对于 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

变更日志

版本 描述
8.0.0 socket 现在是一个 Socket 实例;以前是一个 resource

示例

示例 #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));
?>

参见

添加备注

用户贡献的备注 4 条备注

3
recycling dot sp dot am at gmail dot com
14 年前
这里只有两点说明
- 在 UNIX 上,如果设置了 SO_DEBUG,则 php 程序需要有效的用户 ID 为 0。
- 在套接字上激活 SO_OOBINLINE 等效于为与该套接字一起使用的每个接收函数传递 MSG_OOB 标志(例如:socket_recv、socket_recvfrom)。
4
Chad Lavoie
13 年前
如果使用 Unix 套接字,并且想要使用 SO_PEERCRED,则可以使用数字 17 作为 optname(以及 SOL_SOCKET 作为级别)。将返回连接进程的 PID。
1
prennings at gmail dot com
10 年前
我正在尝试使用此选项来使用具有相同主机名和相同端口(IRC)的多个套接字连接。但是为此需要的套接字函数是 SO_REUSEPORT。

尽管大多数 Linux 发行版尚未在其发行版中正式实现。

但是对于 Debian,可以安装一个补丁来使其工作

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

它有一些工作要做,但在一段时间后我成功运行了它(Debian 新手),也许其他人也面临着和我一样的问题。
0
skydiablo at gmx dot net
2 年前
要在专用接口上接收 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;
}
}
?>
To Top