在 PHP 中使用 fsockopen() 和 fgets() 时, while() 循环如何不停止?
这是小型 PHP IRC 机器人的基本连接代码。问题是,在从 IRC 服务器接收到数据之前,while() 循环似乎不会超出 fgets() 的范围。我希望 while() 循环能够迭代,无论 IRC 服务器是否尚未发送数据。这可能吗?
$socket = fsockopen($config['irc_server'], $config['port']);
while (1)
{
$data = fgets($socket, 128);
echo '[RECEIVE] ' . $data;
$recv = explode(' ', $data);
if ($recv[0] == 'PING')
{
send('PONG', $recv[1]);
}
}
This is the basic connection code for a small PHP IRC bot. The problem is that it seems that the while() loop does not progress beyond fgets() until it receives data from the IRC server. I want the while() loop to iterate regardless if the IRC server has not yet sent data. Is this possible?
$socket = fsockopen($config['irc_server'], $config['port']);
while (1)
{
$data = fgets($socket, 128);
echo '[RECEIVE] ' . $data;
$recv = explode(' ', $data);
if ($recv[0] == 'PING')
{
send('PONG', $recv[1]);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
查看 socket_* 函数,包括以下函数:
socket_set_nonblock
您还可以将非块标志传递给 socket_recv
这是强制性的快速和肮脏的示例(没有错误检查)
Check out the socket_* functions including this one:
socket_set_nonblock
You can can also pass a non-block flag to socket_recv
Here is the obligatory quick and dirty example (no error checking)
看看ftell。这是 php 文档中的相关示例:
Take a look at ftell. Here is a related example from the php documentation:
stream_select() 可以判断套接字上是否有数据可供读取。但 fgets() 直到出现换行符或流结束时才会返回。因此,您必须使用 fread() 并自行拆分数据。
顺便说一句:您可能还对 PEAR::Net_SmartIRC 包感兴趣。
stream_select() can tell if data is available for reading on the socket. But fgets() doesn't return until there's a line break or the stream ends. So you'd have to use fread() instead and split the data yourself.
btw: You might also be interested in the PEAR::Net_SmartIRC package.
我不明白这有什么问题。如果该代码什么也没收到,您希望它做什么?
目前,它只会再次循环回到 fgets,因此您只是在无缘无故地忙于等待而消耗周期。在这种情况下,阻止是正确的行为。
I don't see how that's a problem. What do you want that code to do if it receives nothing?
At the moment, it'll just loop around back to the fgets again, so you're just burning cycles busy-waiting for no good reason. Blocking is the correct behaviour in this instance.