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 に答える