socket_select
在指定的超时套接字数组上运行select()系统调用
函数名: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 ] )
参数:
返回值:
示例:
$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()等待事件发生,然后根据返回结果处理不同的情况,如有新的客户端连接、客户端断开连接和接收客户端发送的数据。这种方式可以在单个线程中同时处理多个客户端连接,提高服务器的性能和并发处理能力。