简体   繁体   English

PHP套接字服务器挂起

[英]PHP Socket Server Hangs

I've worked hours and hours on this, and I can't figure it out. 我已经花了几个小时的时间,但我无法弄清楚。 I've browsed the posts on here trying to find the solution also and to no avail. 我浏览了这里的帖子,试图找到解决方案,但无济于事。

I have a Socket Server setup for my browser-based game. 我为基于浏览器的游戏安装了Socket Server。 I've stripped it down trying to find the issue, and it seems that fread is hanging because if I comment out "fread($fp, 10024);" 我已将其剥离以查找问题,似乎fread正在挂起,因为如果我注释掉“ fread($ fp,10024);”, then it runs fine, but of course doesn't read the response. 那么它运行正常,但当然不会读取响应。

While I debug this, I've broken the files down to the basics. 在调试时,我将文件分解为基本内容。

I have the Socket Server: ChatServer.php 我有套接字服务器: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);

Then I have Test.php which should open the socket and read a response. 然后我有Test.php,它应该打开套接字并读取响应。

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

$errstr doesn't display an error, because when I start ChatServer.php then reload Test.php, it never reloads. $ errstr不会显示错误,因为当我启动ChatServer.php然后重新加载Test.php时,它永远不会重新加载。 It hangs for minutes and lags my entire server. 它挂了几分钟,滞后了我的整个服务器。 I'm running on a VPS. 我正在VPS上运行。 This worked fine before, then suddenly stopped working, and I can't figure out why. 在此之前效果很好,然后突然停止工作,我不知道为什么。

Edit: Thanks to GigaWatt, I was able to get it working. 编辑:感谢GigaWatt,我得以使其工作。 Here is the code I used if you have the same issue. 如果您遇到相同的问题,这是我使用的代码。 :) :)

    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);

Just use stream_get_meta_data and then unread_bytes. 只需使用stream_get_meta_data然后使用unread_bytes。

The call to socket_read is a blocking call, meaning everything stops until the specified number of bytes have been read. socket_read的调用是一个阻塞调用,这意味着所有操作都将停止,直到已读取指定数量的字节为止。

If you need to continue processing, consider using stream_get_meta_data (the unread_bytes value) to check how much unread data is waiting. 如果需要继续处理,请考虑使用stream_get_meta_dataunread_bytes值)来检查有多少未读数据正在等待。
Once it reaches the desired threshold, then call socket_read . 一旦达到所需的阈值, 调用socket_read

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

It does exactly what you tell it to: waits for 12048 / 10024 bytes of data or socket being closed. 它完全按照您的指示进行操作:等待12048/10024字节的数据或套接字被关闭。

You might be interested in using a non-blocking socket ( socket_set_nonblock/stream_set_blocking ) and a socket_select loop or libevent. 您可能对使用非阻塞套接字( socket_set_nonblock/stream_set_blocking )和socket_select循环或libevent socket_select

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM