php socket_select 为什么只能被检测到一次可读??

灰色v碰触
  • 2.8k

php socket_select 为什么只能被检测到一次可读??

有如下代码:

server.php(问题包含在代码块里了,麻烦看下,谢谢)


$ip   = '127.0.0.1';
$port = 9101;

$res = socket_create(AF_INET , SOCK_STREAM , SOL_TCP);

socket_bind($res , $ip , $port);

socket_listen($res);

socket_set_option($res , SOL_SOCKET , SO_REUSEADDR , true);

$read = [];
$write = [];
$except = [];

socket_set_nonblock($res);

$count = 1;

while (true)
{
    $identifier = socket_accept($res);

    $read[]  = $res;

    if (is_resource($identifier)) {
        $read[]  = $identifier;
        $write[] = $identifier;
    }
    
    // select 监测哪些套接字资源可读 或 可写
    // 这边很奇怪的是:
    // 一个client.php链接后,每个一定时间向服务器写入数据 + 读取服务端响应
    // 结果这边只能检测出一次 `client.php` 写入的数据,其后一直未不可读!
    // 却一直可收到服务端写入的数据
    // 这是为什么??
    socket_select($read , $write , $except , 0);

    foreach ($read as $v)
    {
        $msg = socket_read($v , 1024);

        echo '客户端发送数据:' . $msg . PHP_EOL;
    }

    foreach ($write as $v)
    {
        socket_write($v , 'service reponse');
    }

    echo '循环次数' . $count++ . PHP_EOL;

    sleep(2);
}

client.php


$ip   = '127.0.0.1';
$port = 9101;

$res = socket_create(AF_INET , SOCK_STREAM , SOL_TCP);

$connect = socket_connect($res , $ip , $port);


if (!$connect) {
    exit('链接失败,失败信息:' . socket_strerror(socket_last_error()) . PHP_EOL);
}

$count = 1;

while (true)
{
    $buffer = 'client 2 data';

    socket_write($res , $buffer);

    $msg = socket_read($res , 1024);

    if (!empty($msg)) {
        echo '服务端响应数据:' . $msg . PHP_EOL;
    }

    sleep(4);
}
回复
阅读 3.9k
1 个回答

socket_select($read , $write , $except , 0);
你用的不对. 这儿是引用传值, $read , $write , $except 这三变量会被修改.

在你的代码里, $read 只会剩下一个值, 就是你client现在正在使用的那个连接.

应该给$read重新赋值一下.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏