无限的 feof 循环

4

使用feoffgets时,脚本会一直运行直到1分钟的最大执行时间标记。

my $socket = new IO::Socket::INET(
    LocalPort => '5000',
    Proto     => 'tcp',
    Listen    => 5,
    ReuseAddr => 1,
);

my $connection = $socket->accept();

$connection->send("\0"); # makes PHP send the contents

my $data = <$connection>;
if($data != "1234") {
    $connection->send("not accepted");
} else {
    $connection->send("accepted");
}

$connection->close();

PHP在60秒内不会发送内容。使用fread时,它几乎立即传递数据(但只会返回\0)。

$socket = fsockopen('tcp://192.168.56.101', 5000); // virtualbox IP
fwrite($socket, '1234');

echo fread($socket, 128);

fclose($socket);

上述脚本将几乎立即执行,但只会获取\0
while(!feof($socket)) {
    echo fread($socket, 128);
}

使用上述脚本将延迟60秒后才发送任何数据。

问题

如何让PHP在不超过60秒的情况下发送并检索来自Perl套接字的所有数据?

1个回答

2

PHP实际上是立即发送数据的;问题在于Perl没有对其进行任何处理。如果您执行以下操作:

my $data = <$connection>;
print $data; #add this line
if($data != "1234") { ....

然后使用Ctrl-C(Windows系统——如果您使用Linux,不知道命令是什么),杀死PHP脚本,Perl脚本将立即输出“1234”。 它卡在尖括号运算符上,因为那是一个readline(即它正在寻找换行符但从未找到)。 以下任何一种方法都可以使您的代码正常工作:

//in the PHP file
fwrite($socket, "1234\r\n");

或者

#in the Perl file (instead of my $data = <$connection>)
my $data;
$connection->recv($data, 1024);

编辑:在实施更改之前,请查看下面的评论。正如hobbs所提到的,recv可能不是最好的选择,尽管它可以工作,因为它不会寻找换行符并且输入很短。以某种方式发送换行符(第一个建议的变体)可能是更好的选择。


1
...或者让PHP发送一个换行符,或者使用长度前缀,或者某种方式让监听器知道它实际上已经接收到了所有数据。recv在这里并不是100%正确的,尽管在这样的简短输入下它可能会正常工作。 - hobbs
1
@hobbs - recv 不是完全可靠的:同意。我只是想解释为什么他看到脚本挂起并展示使用一个不关心换行符的函数可以成功地继续执行脚本。 - ChicagoRedSox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接