如何在PHP中存储多个流套接字资源

How to store multiple stream socket resources in PHP?

本文关键字:套接字 资源 存储 PHP      更新时间:2023-09-26

我有一个使用stream_socket_server()创建的TCP服务器。然后我有一个无休止的循环调用stream_socket_accept()。到目前为止,这是有效的,并且接受了尽可能多的连接。但是,如果我试图将接受的连接存储在一个数组中,例如,stream_socket_accept()函数将停止接受进一步的连接。只有当我将流资源添加到array()中时,才会发生这种情况。这里有一个例子:

<?php
$errcode = $errmsg = null;
$sock = stream_socket_server('tcp://0.0.0.0:65000', $errcode, $errmsg, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN);
if ($sock === false) {
    stream_set_blocking($sock, 0);
}
$storage = array();
for (;;) {
    $con = @stream_socket_accept($sock, 0);
    if ($con !== false) {
        echo "Connection received'n";
        $storage[] = $con;//After this line, some of the next stream_socket_accept will not accept further connections
        $con = @stream_socket_accept($sock, 0);
    }
    usleep(20000);
}

您可以通过打开许多这样的连接来测试脚本(在bash/zsh/whatever中):

for a in {1..100}; do telnet localhost 65000 &; done

更奇怪的是,如果我试图从浏览器打开100个连接,只有一个会被接受:

for (var x = 0; x < 100; x++) {
    var sock = new WebSocket("ws://localhost:65000", "echo");
}

要测试这一点,请将上面的JavaScript保存为Google Chrome中的一个片段并运行它。请注意,如果未将连接添加到$storage数组,JavaScript代码也将接受其100次连接尝试,谢谢!

感谢您的帮助。

大多数接受的连接资源,在未存储时,由于分配给同一资源变量的新stream_socket_accept(),在不再被引用后会自动关闭和释放,因此不会同时有一百个连接。您的设置不支持那么多。

我不明白为什么第15行有另一个stream_socket_accept,你应该只有一个。

您也可以添加一个超时,例如1(秒)而不是0,并删除@,因为这是一种糟糕的做法(您可能有一个大问题,永远不会知道):$con = stream_socket_accept($sock, 1);