2
use strict; use warnings;
use IO::Socket;
use IO::Select;
my $read_select  = IO::Select->new();
my $write_select = IO::Select->new();

my $socket = IO::Socket::INET->new(
            LocalHost => '127.0.0.1',
            LocalPort => '5556',
            Proto => 'tcp',
            Listen => 50,
            Reuse => 1,
 ) or die "Could not create socket: $!";

 print "Socket Created . Waiting for connection ...\n";

 ## poll to accept new connection or to receive data from a connection

 $read_select->add($socket);

 print "Added socket to read list ";
 my $reade;
 my $newconn;
 my @read;
 my @write;
 while(1) {
    @read = $read_select->can_read();

    foreach my $reade(@read) {
            if($reade == $socket) {
                    print "New conn received";
                    my $newconn = $reade->accept();
                    $write_select->add($newconn);

            }
            else {
                    print "data received";
            }
    }
 }
 @write = $write_select->can_write();

 foreach my $write(@write) {
    $write->send("got ur data");
 }

select ステートメントを使用して接続をポーリングしようとしています。無限ループを使用すると、接続が受け入れられないのはなぜですか。while(1) がなくても問題なく動作します

4

1 に答える 1

2

ここで I/O バッファリングに悩まされていると思います。Perl はすべての入力と出力をバッファリングします。通常、行全体を受信するまで端末に出力しません。

コードはおそらく で動作してwhile(1)いますが、ターミナルへの出力がバッファリングされているため、デバッグ プリント ステートメントの出力を確認できません。ループを 2 回目に通過すると、$read_select->can_read()永久にブロックされるため、print ステートメントの出力は表示されません。

\n各 print ステートメントの末尾に追加するだけで、おそらくこれを修正できます。別のオプションは設定$| = 1;です。これにより、バッファリングが無効になります。バッファリングの詳細については、 perlvar の議論を$|参照してください。

于 2013-04-04T11:01:29.837 に答える