PHP套接字服务器挂起

时间:2014-05-19 15:28:53

标签: php sockets

我已经花了几个小时和几个小时做这件事,我无法弄明白。我已经浏览了这里的帖子,试图找到解决方案也无济于事。

我为基于浏览器的游戏设置了套接字服务器。我试图找到问题时将其剥离,看起来恐惧正在悬挂,因为如果我发表评论" 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。

2 个答案:

答案 0 :(得分:2)

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

如果您需要继续处理,请考虑使用stream_get_meta_dataunread_bytes值)检查未读数据的数量。
达到所需的阈值后,然后调用socket_read

http://us3.php.net/manual/en/function.stream-get-meta-data.php

答案 1 :(得分:1)

它完全符合您的要求:等待12048/10024字节的数据或套接字关闭。

您可能对使用非阻塞套接字(socket_set_nonblock/stream_set_blocking)和socket_select循环或libevent感兴趣。

相关问题