0

这是一个小型 PHP IRC 机器人的基本连接代码。问题是,似乎 while() 循环在从 IRC 服务器接收数据之前不会超出 fgets()。无论 IRC 服务器是否尚未发送数据,我都希望 while() 循环进行迭代。这可能吗?

$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]);
    }
}
4

4 回答 4

2

查看 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 */ }
于 2009-12-11T00:38:57.007 回答
0

看看 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";}

?>
于 2009-12-11T00:27:02.627 回答
0

stream_select()可以判断数据是否可用于在套接字上读取。但是 fgets() 在换行或流结束之前不会返回。因此,您必须改用fread()并自己拆分数据。

顺便说一句:您可能还对PEAR::Net_SmartIRC包感兴趣。

于 2009-12-11T00:38:04.903 回答
-1

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

我不明白这是怎么回事。如果该代码没有收到任何内容,您希望该代码做什么?

目前,它只会再次循环回到 fgets,所以你只是在忙着循环等待,没有充分的理由。在这种情况下,阻塞是正确的行为。

于 2009-12-11T00:25:52.160 回答