這裡只有 2 個注意事項
- 在 UNIX 上,如果設定了 SO_DEBUG,PHP 程式需要有效的使用者 ID 為 0。
- 在 socket 上啟用 SO_OOBINLINE 相當於將 MSG_OOB 旗標傳遞給每個用於該 socket 的接收函式(例如: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
參數指定選項所在的協定層級。例如,要擷取通訊端層級的選項,可以使用 SOL_SOCKET
作為 level
參數。其他層級,例如 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() 將會失敗並返回錯誤。 |
陣列。該陣列將包含兩個鍵: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 |
回報輸入操作的逾時值。 | 陣列。該陣列將包含兩個鍵:sec,它是逾時值的秒數部分,以及 usec,它是逾時值的微秒部分。 |
SO_SNDTIMEO |
回報指定輸出函式因流量控制阻止資料傳送而阻塞的時間量的逾時值。 | 陣列。該陣列將包含兩個鍵:sec,它是逾時值的秒數部分,以及 usec,它是逾時值的微秒部分。 |
SO_SNDLOWAT |
回報 socket 輸出操作要處理的最小位元組數。 |
int(整數) |
TCP_NODELAY |
回報 Nagle TCP 演算法是否已停用。 | int(整數) |
MCAST_JOIN_GROUP |
加入多播群組。 |
陣列,鍵值包含 "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_IF 和 IPV6_MULTICAST_IF 之間的介面差異。 |
IPV6_MULTICAST_IF |
IPv6 多播封包的輸出介面。 | 與 IP_MULTICAST_IF 相同。 |
IP_MULTICAST_LOOP |
IPv4 封包的多播迴路政策,可啟用或停用輸出多播的迴路,該多播必須已事先加入。然而,其效果在 Unix 或 Windows 系統上有所不同,前者在接收路徑上,而後者在發送路徑上。 |
整數 ( 0 或 1 )。對於 socket_set_option() 來說,任何值都會被接受並根據一般的 PHP 規則轉換為布林值。 |
IPV6_MULTICAST_LOOP |
類似於 IP_MULTICAST_LOOP ,但適用於 IPv6。 |
整數。請參考 IP_MULTICAST_LOOP 。 |
IP_MULTICAST_TTL |
外送 IPv4 多播封包的存活時間 (time-to-live)。這應該是一個介於 0(不離開介面)和 255 之間的值。預設值為 1(僅到達本地網路)。 | 整數,介於 0 到 255 之間。 |
IPV6_MULTICAST_HOPS |
類似於 IP_MULTICAST_TTL ,但適用於 IPv6 封包。值 -1 也會被接受,表示應使用路由預設值。 |
整數,介於 -1 到 255 之間。 |
SO_MARK |
在 Linux 上設定套接字的識別碼,以進行封包過濾。 | int(整數) |
SO_ACCEPTFILTER |
在監聽的套接字上新增接受過濾器 (FreeBSD/NetBSD)。在 FreeBSD 上需要事先載入接受過濾器核心模組(例如 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 親和性。 | 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));
?>
這裡只有 2 個注意事項
- 在 UNIX 上,如果設定了 SO_DEBUG,PHP 程式需要有效的使用者 ID 為 0。
- 在 socket 上啟用 SO_OOBINLINE 相當於將 MSG_OOB 旗標傳遞給每個用於該 socket 的接收函式(例如:socket_recv、socket_recvfrom)。
如果使用 Unix Sockets,並且您想使用 SO_PEERCRED,您可以使用數字 17 作為 optname(以及 SOL_SOCKET 作為 level)。將會返回連線程序的 PID。
我正在嘗試使用這個選項來使用相同的Hostname和相同的端口(IRC)進行多個 socket 連線。然而, hierfür benötigte Socket-Funktion ist SO_REUSEPORT. (原文如此,應更正為:然而, hierfür benötigte Socket-Funktion ist SO_REUSEPORT。這句話的意思是:然而,這需要用到 SO_REUSEPORT 這個 Socket 函式。)
儘管大多數 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;
}
}
?>