Php - fgets()用socket读取,仍然无法正常工作

时间:2014-04-13 20:17:39

标签: php sockets timeout fgets

到目前为止,我花了很多时间在这个fgets()问题上没有任何成功。 我通过HTTP套接字接收来自不同来源的数据。它工作得很好,直到现在我有更多不同的来源。

我的目标只是摆脱php的执行超时,只知道它在15秒后超时,但继续使用下一个源。

这是我的一小段代码:

//This is just from php.net, found out that it works pretty good
$time = time();
while (!($temp = fsockopen($host, $port, $errNo, $errMessage, $timeout)))
{
    if ((time() - $time) >= $timeout)
    {
        socket_close($temp);
        return false;
    }
    sleep(1);
}

    //If PHP returns an error
 if (!($temp)) {
    echo 'Socket could not be opened.<br/>';
    return false;
}

$return = "";

if (!fwrite($temp, $out)) {
    print_r(error_get_last());
    return false;
}

    //Timeout set to 15 seconds
    stream_set_blocking($temp, 0);
    $start = time();

    while ((time() < ($start + 15))) {

        //(Last lines always finishes like this)
        if (substr(trim($return),-9) == '"id":"1"}') {
            break;
        } else {
            $return .= fgets($temp, 512);
        }
    }
    fclose($temp);

经过一些测试后,我发现非阻塞套接字为这段代码提供了更好的结果,但是在收到4个数据源的数据后仍然阻塞。 (我试图改变顺序,因此它不依赖于源)

我尝试使用stream_set_timeout($ temp)并检查循环中的标志状态,但它并没有改变。

编辑:我忘了提及它,但脚本在fgets()的行停止(PHP执行超时为30秒)。

任何线索?

干杯!

2 个答案:

答案 0 :(得分:0)

fgets()length参数文档:

  

读取长度 - 读取1个字节,换行符(包含在返回值中)或EOF(以先到者为准)时结束。如果没有指定长度,它将继续从流中读取,直到它到达行尾。

在您的情况下,这些条件都不会满足,这将使脚本无限期地等待输入。

要使用stream_set_timeout()设置的套接字超时,您可以使用fread()代替fgets(),这将支持设置超时。与fgets()的唯一区别在于fread()一次不获取一行,而是整个length个字节数。

答案 1 :(得分:0)

感谢大家的支持,

最后,它不能正常工作的主要原因是答案需要的时间比以前要长一些。

然而,有时甚至不会对fgets进行攻击的原因尚不清楚,但我通过以下方式解决了这个问题:     - 阅读标题     - 获取标题的Content-length     - 等待指定的时间(因为这是远程服务器需要一些时间发送的数据部分)     - 然后fgets($handle, $content_lenght -1)

我仍然不明白为什么我必须等待,通常是fgets()如果套接字处于阻塞模式,应该等待并读取直到你说的EOF(或定义的长度),但是有在我的情况下,总是在数据行的末尾有一个EOF,无论如何我指的是长度......

从3G连接的世界另一端的服务器获取数据最多需要10秒钟(不能做得更糟),所以我仍然不明白为什么达到了30秒的exec ..

无论如何,至少它是有效的,不完美,但它有效。

干杯