在 PHP 中使用 fsockopen() 和 fgets() 时, while() 循环如何不停止?

发布于 2024-08-14 03:19:50 字数 397 浏览 9 评论 0原文

这是小型 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

原谅我要高飞 2024-08-21 03:19:50

查看 socket_* 函数,包括以下函数:

socket_set_nonblock

您还可以将非块标志传递给 socket_recv

这是强制性的快速和肮脏的示例(没有错误检查)

/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($socket, $address, $service_port);
while (false === ($bytes = socket_recv($socket, $buf, 2048, MSG_DONTWAIT))) 
{ /* do stuff while waiting for data */ }

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)

/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($socket, $address, $service_port);
while (false === ($bytes = socket_recv($socket, $buf, 2048, MSG_DONTWAIT))) 
{ /* do stuff while waiting for data */ }
巾帼英雄 2024-08-21 03:19:50

看看ftell。这是 php 文档中的相关示例:

#!/usr/bin/php4 -q
<?
#following will hang if nothing is piped:
#$sometext = fgets(STDIN, 256)

$tell = ftell(STDIN);

if (is_integer($tell)==true) 
  {echo "Something was piped: ".fread(STDIN,256)."\n";}
else 
  {echo "Nothing was piped\n";}

?>

Take a look at ftell. Here is a related example from the php documentation:

#!/usr/bin/php4 -q
<?
#following will hang if nothing is piped:
#$sometext = fgets(STDIN, 256)

$tell = ftell(STDIN);

if (is_integer($tell)==true) 
  {echo "Something was piped: ".fread(STDIN,256)."\n";}
else 
  {echo "Nothing was piped\n";}

?>
迷雾森÷林ヴ 2024-08-21 03:19:50

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.

初见 2024-08-21 03:19:50

问题是,在从 IRC 服务器接收到数据之前,while() 循环似乎不会超出 fgets() 的范围。

我不明白这有什么问题。如果该代码什么也没收到,您希望它做什么?

目前,它只会再次循环回到 fgets,因此您只是在无缘无故地忙于等待而消耗周期。在这种情况下,阻止是正确的行为。

The problem is that it seems that the while() loop does not progress beyond fgets() until it receives data from the IRC server.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文