到目前为止,我花了很多时间在这个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秒)。任何线索?
干杯!
答案 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 ..
无论如何,至少它是有效的,不完美,但它有效。
干杯