php socket_select
时间: 2023-08-01 20:10:52 浏览: 39
socket_select() 是 PHP 中的一个函数,用于监听多个 socket 上是否有数据可读、可写或发生错误等事件。它的语法如下:
```
int socket_select ( array &$read , array &$write , array &$except , int $tv_sec [, int $tv_usec = 0 ] )
```
其中,$read、$write 和 $except 分别是包含 socket 句柄的数组,用于监听是否有可读、可写或异常事件。$tv_sec 和 $tv_usec 表示超时时间,单位是秒和微秒。当函数成功执行时,返回被监听到的 socket 数量,失败则返回 false。
这个函数通常被用于非阻塞式 socket 编程中,可以让程序在等待 socket 事件时不会被阻塞,而是可以执行其他的操作,提高程序的效率。
相关问题
PHP socket.on
`socket.on` 是一个 JavaScript 中的事件处理函数,用于在客户端与服务器之间建立 socket 连接时处理事件。在 PHP 中没有直接的 `socket.on` 函数,但可以通过在服务器端使用 `socket_select` 函数实现类似的功能。
`socket_select` 函数可以用于等待多个 socket 上的事件,并在事件发生时执行相应的代码。下面是一个简单的示例,演示如何使用 `socket_select` 函数在 PHP 服务器端处理客户端连接事件:
```php
<?php
// 创建 socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!$socket) {
echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
exit;
}
// 绑定地址和端口
$address = '127.0.0.1';
$port = 8888;
if (!socket_bind($socket, $address, $port)) {
echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($socket)) . "\n";
exit;
}
// 监听连接请求
if (!socket_listen($socket, 5)) {
echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($socket)) . "\n";
exit;
}
// 等待连接
echo "Waiting for client to connect...\n";
$sockets = array($socket);
while (true) {
$readSockets = $sockets;
$writeSockets = null;
$exceptSockets = null;
$numSockets = socket_select($readSockets, $writeSockets, $exceptSockets, null);
if ($numSockets === false) {
echo "socket_select() failed: reason: " . socket_strerror(socket_last_error($socket)) . "\n";
break;
} elseif ($numSockets === 0) {
continue;
}
// 有新的连接请求
if (in_array($socket, $readSockets)) {
$clientSocket = socket_accept($socket);
if (!$clientSocket) {
echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($socket)) . "\n";
continue;
}
echo "New client connected\n";
$sockets[] = $clientSocket;
$key = array_search($socket, $readSockets);
unset($readSockets[$key]);
}
// 处理其他 socket 上的事件
foreach ($readSockets as $readSocket) {
$msg = socket_read($readSocket, 1024);
if ($msg === false) {
$key = array_search($readSocket, $sockets);
unset($sockets[$key]);
echo "Client disconnected\n";
} else {
echo "Received message from client: $msg\n";
$response = "Hello, client!";
socket_write($readSocket, $response, strlen($response));
}
}
}
// 关闭 socket
foreach ($sockets as $s) {
socket_close($s);
}
socket_close($socket);
```
在上面的示例中,我们使用 `socket_select` 函数等待多个 socket 上的事件。当有新的连接请求时,我们接受连接并将新的 socket 添加到 `$sockets` 数组中。当一个连接断开时,我们从 `$sockets` 数组中删除对应的 socket。对于其他 socket 上的事件,我们从中读取消息并向客户端发送响应。
需要注意的是,`socket_select` 函数会阻塞当前进程,直到有事件发生或超时。在实际中,您可能需要使用多个进程或线程来处理多个 socket 上的事件,以避免阻塞问题。
用php socket写一段聊天室的代码
以下是一个简单的 PHP Socket 聊天室的代码样例:
```
<?php
// 创建一个 TCP/IP socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
echo "socket_create() failed: " . socket_strerror(socket_last_error()) . "\n";
exit();
}
// 绑定 socket 到一个 IP 地址和端口
$address = 'localhost';
$port = 8888;
$result = socket_bind($socket, $address, $port);
if ($result === false) {
echo "socket_bind() failed: " . socket_strerror(socket_last_error($socket)) . "\n";
exit();
}
// 监听连接请求
$result = socket_listen($socket, 3);
if ($result === false) {
echo "socket_listen() failed: " . socket_strerror(socket_last_error($socket)) . "\n";
exit();
}
echo "Server started on $address:$port\n";
$clients = array();
while (true) {
// 监听所有连接的 socket,看是否有新的连接进来
$read = array_merge(array($socket), $clients);
$write = NULL;
$except = NULL;
$result = socket_select($read, $write, $except, 0);
if ($result === false) {
echo "socket_select() failed: " . socket_strerror(socket_last_error($socket)) . "\n";
break;
} else if ($result > 0) {
// 如果有新连接进来,处理连接请求
if (in_array($socket, $read)) {
$new_client = socket_accept($socket);
if ($new_client !== false) {
$clients[] = $new_client;
echo "New client joined\n";
}
$key = array_search($socket, $read);
unset($read[$key]);
}
// 读取客户端发送的消息
foreach ($read as $client) {
$data = socket_read($client, 1024);
if ($data === false) {
echo "socket_read() failed: " . socket_strerror(socket_last_error($client)) . "\n";
$key = array_search($client, $clients);
unset($clients[$key]);
socket_close($client);
continue;
}
$data = trim($data);
if (!empty($data)) {
echo "Received message: $data\n";
// 将消息广播给其他客户端
foreach ($clients as $c) {
if ($c === $socket || $c === $client) {
continue;
}
socket_write($c, "$data\n");
}
}
}
}
}
// 关闭所有连接
foreach ($clients as $client) {
socket_close($client);
}
socket_close($socket);
?>
```
这个聊天室程序可以同时处理多个客户端连接,并将客户端发送的消息广播给其他客户端。你可以将这个代码保存为一个 PHP 文件,然后在命令行中运行它,即可启动一个简单的 Socket 聊天室。