Php-fgets()正在使用套接字读取,仍然无法正常工作
我在这个fgets()问题上花了很多时间,到现在为止都没有成功。 我通过HTTP套接字接收来自不同来源的数据。直到现在我有了更多不同的信息来源,这一切都很顺利 我的目标是消除php的执行超时,只需知道它在15秒后超时,然后继续下一个源代码 以下是我的一小段代码:Php-fgets()正在使用套接字读取,仍然无法正常工作,php,sockets,timeout,fgets,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, $po
//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);
//这是来自php.net的,我们发现它工作得非常好
$time=time();
而(!($temp=fsockopen($host、$port、$errNo、$errMessage、$timeout)))
{
如果((time()-$time)>=$timeout)
{
插座关闭($temp);
返回false;
}
睡眠(1);
}
//如果PHP返回错误
如果(!($temp)){
echo“无法打开套接字。
”;
返回false;
}
$return=“”;
如果(!fwrite($temp,$out)){
打印(错误获取上次());
返回false;
}
//超时设置为15秒
流设置阻塞($temp,0);
$start=time();
而((time()<($start+15))){
//(最后一行总是这样结束)
if(substr(trim($return),-9)='“id”:“1”}'){
打破
}否则{
$return.=fgets($temp,512);
}
}
fclose(临时);
经过一些测试,我发现一个非阻塞套接字为这段代码提供了更好的结果,但是在收到4个源的数据后,它仍然阻塞。(我试图更改顺序,使其不依赖于源)
我尝试使用stream\u set\u timeout($temp)并检查循环中标志的状态,但它没有改变任何东西
编辑:我忘了提到它,但是脚本在fgets()行停止(PHP执行超时30秒)
有什么线索吗
干杯 将
长度
参数的文档记录到:
读取长度为-1字节、换行符(包含在返回值中)或EOF(以先到者为准)时,读取结束。如果未指定长度,它将一直从流中读取,直到到达行的末尾
在您的情况下,这些条件都不会满足,这将使脚本无限期地等待输入
要使用由
stream\u set\u timeout()
设置的套接字超时,可以使用而不是fgets()
,这将遵守设置的超时。fgets()
的唯一区别在于fread()
不会一次提取一行,而是整个长度
字节数。谢谢大家的帮助
最后,它不能正常工作的主要原因是答案需要比过去更长的时间才能到达
但是,它有时会卡在fgets()
上,有时不卡在fgets()上的原因仍然不清楚,但我用以下方法解决了它:
- 阅读标题
- 获取标题的
内容长度
- 等待指定的时间(因为这是远程服务器需要一些时间才能发送的数据部分)
- 然后
fgets($handle,$content\u length-1)
我仍然不明白的是,为什么我必须等待,通常情况下,如果套接字处于阻塞模式,fgets()
应该等待并读取,直到您所说的EOF(或定义的长度),但在我的情况下,数据行的末尾总是有EOF,无论如何,我都在指定长度
而且从世界另一端的3G服务器上获取数据最多需要10秒(做得再差不过了),所以我仍然不明白为什么会达到30秒的exec
不管怎么说,至少它起作用了,不是很完美,但它起作用了
Cheers是否有理由对HTTP请求使用域套接字连接而不是更高级别的库(如cURL)?它消除了您现在处理的许多微观管理难题。实际上,我无法控制运行此脚本的服务器。。。至少就目前而言,cURL是否提供了最好的性能?我现在正在积极研究这个问题……嗯,问题是在这种情况下,为什么它有时有效,有时无效?所有源都是完全相同类型的服务器。。。不管怎样,我也会和fread再试试,我刚有个主意。谢谢你的回答,我会让你知道的。为什么它有时有效,有时无效?如果不了解发送服务器上的实现,则无法回答该问题(因为您的脚本在未从该服务器接收换行符或EOF时中断)。希望我的建议能有所帮助!