PHP Socket 服务器挂起

标签 php sockets

我花了很多时间研究这个问题,但我无法弄清楚。我浏览了这里的帖子,试图找到解决方案,但没有成功。

我为我的基于浏览器的游戏设置了套接字服务器。我已经将其剥离以试图找到问题,并且 fread 似乎挂起,因为如果我注释掉“fread($fp, 10024);”然后它运行良好,但当然不会读取响应。

在调试此文件时,我已将文件分解为基础内容。

我有套接字服务器:ChatServer.php

set_time_limit(0);
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_get_option($sock, SOL_SOCKET, SO_REUSEADDR);
socket_bind($sock, "127.0.0.1", "9990");
socket_listen($sock, 4);

$chatContent = "Testing, 1, 2, 3.";
do
{
    $childSocket = socket_accept($sock);
    $incomingData = socket_read($childSocket, 12048);

    socket_write($childSocket, $chatContent, strlen($chatContent));
} while(true);

然后我有 Test.php,它应该打开套接字并读取响应。

$fp = fsockopen("127.0.0.1", "9990", $errno, $errstr, 5);
echo $errstr . "<br />";
echo fread($fp, 10024);

$errstr 不显示错误,因为当我启动 ChatServer.php 然后重新加载 Test.php 时,它永远不会重新加载。它挂起几分钟并落后于我的整个服务器。我在 VPS 上运行。以前工作正常,然后突然停止工作,我不明白为什么。

编辑:感谢 GigaWatt,我能够让它工作。如果您遇到同样的问题,这是我使用的代码。 :)

    set_time_limit(0);
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_get_option($sock, SOL_SOCKET, SO_REUSEADDR);
socket_bind($sock, "127.0.0.1", "9990");
socket_listen($sock, 4);

$chatContent = "Testing, 1, 2, 3.";
do
{
    $childSocket = socket_accept($sock);
    $meta = stream_get_meta_data($sock);

    if($meta['unread_bytes'] > 0) {
        $incomingData = socket_read($childSocket, $meta['unread_bytes']);
    }

    socket_write($childSocket, $chatContent, strlen($chatContent));
} while(true);

只需使用stream_get_meta_data,然后使用unread_bytes。

最佳答案

socket_read 的调用是阻塞调用,这意味着一切都会停止,直到读取指定数量的字节为止。

如果您需要继续处理,请考虑使用stream_get_meta_data(unread_bytes值)来检查有多少未读数据正在等待。
一旦达到所需的阈值,然后调用socket_read

https://www.php.net/manual/en/function.stream-get-meta-data.php

关于PHP Socket 服务器挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23741634/

相关文章:

php - mysql无法插入8列的表

php - 运行 QTcpServer,如何正确接收或发送数据?

c++ - 如何将addr_in结构分配给uint8_t数组

php - 使用 fopen PHP 获取第一个和第二个元素

php - 安卓ip连接电脑

php - PEAR 邮件发送 CSV 失败

javascript - express + socket.io 跨域

c - 二进制文件不能传输,文本文件可以传输

java - 通过线程中的套接字进行对象输入/输出

c - UDP 数据包未传递 - recvfrom() 永远不会返回