函式名:socket_select()
適用版本:PHP 4 >= 4.3.0, PHP 5, PHP 7
函式描述:socket_select()函式用於在給定的一組socket上進行阻塞式I/O操作的多路複用。它可以同時監視多個socket,以確定哪些socket上有輸入、輸出或異常事件發生。這個函式是基於作業系統提供的select系統呼叫實現的。
語法:int socket_select ( array &$read , array &$write , array &$except , int $tv_sec [, int $tv_usec = 0 ] )
引數:
- $read: 一個包含需要監視讀事件的socket的陣列。
- $write: 一個包含需要監視寫事件的socket的陣列。
- $except: 一個包含需要監視異常事件的socket的陣列。
- $tv_sec: 超時時間,以秒為單位。如果為0,則表示無限等待。
- $tv_usec: 超時時間的微秒部分。預設值為0。
返回值:
- 如果至少有一個socket準備好讀、寫或有異常,則返回值大於0。
- 如果超時時間到達,則返回值為0。
- 如果發生錯誤,則返回值為-1。
示例:
$serverSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($serverSocket, '127.0.0.1', 8888);
socket_listen($serverSocket);
$clientSockets = array($serverSocket);
$write = $except = array();
while (true) {
$read = $clientSockets; // 用於監視讀事件的socket陣列
// 使用socket_select()等待事件發生
if (socket_select($read, $write, $except, 0) < 1) {
continue;
}
// 檢查是否有新的客戶端連線
if (in_array($serverSocket, $read)) {
$clientSocket = socket_accept($serverSocket);
$clientSockets[] = $clientSocket;
echo "New client connected." . PHP_EOL;
// 從讀事件陣列中移除伺服器socket
$key = array_search($serverSocket, $read);
unset($read[$key]);
}
// 處理已連線的客戶端傳送的資料
foreach ($read as $clientSocket) {
$data = socket_read($clientSocket, 1024);
if ($data === false) {
// 客戶端斷開連線
$key = array_search($clientSocket, $clientSockets);
unset($clientSockets[$key]);
socket_close($clientSocket);
echo "Client disconnected." . PHP_EOL;
} else {
// 處理客戶端傳送的資料
echo "Received data: " . $data . PHP_EOL;
}
}
}
// 關閉伺服器socket
socket_close($serverSocket);
上述示例演示了一個簡單的TCP伺服器,使用socket_select()函式來實現多路複用。在迴圈中,透過socket_select()等待事件發生,然後根據返回結果處理不同的情況,如有新的客戶端連線、客戶端斷開連線和接收客戶端傳送的資料。這種方式可以在單個執行緒中同時處理多個客戶端連線,提高伺服器的效能和併發處理能力。