Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Не могу асинхронно считать текст из хендлов.


Автор: stan777 13.4.2007, 16:05
Код

#!/home/stan/bin/perl -w
use strict;
use IO::Socket::INET;
use IO::Select;
use IO::Handle;
use Symbol qw(qualify_to_ref);

my @sockets;
my @ready_read;
my @strings;


sub sysreadline(*;$) {

    my($handle, $timeout) = @_;
    $handle = qualify_to_ref($handle, caller( ));
    my $infinitely_patient = (@_ == 1 || $timeout < 0);
    my $start_time = time( );
    my $selector = IO::Select->new( );
    $selector->add($handle);
    my $line = "";
SLEEP:
    until (at_eol($line)) {
        unless ($infinitely_patient) {
            return $line if time( ) > ($start_time + $timeout);
        }
        # sleep only 1 second before checking again
        next SLEEP unless $selector->can_read(1.0);
INPUT_READY:
        while ($selector->can_read(0.0)) {
            my $was_blocking = $handle->blocking(0);
CHAR:       while (sysread($handle, my $nextbyte, 1)) {
                $line .= $nextbyte;
                last CHAR if $nextbyte eq "\n";
            }
            $handle->blocking($was_blocking);
            # if incomplete line, keep trying
            next SLEEP unless at_eol($line);
            last INPUT_READY;
        }
    }
    return $line;
}

sub at_eol($) { $_[0] =~ /\n\z/ }

my $blank = "Accept: */*\n" .
             "Accept-Language: en-us\n" .
             "Accept-Encoding: deflate\n" .
             "User-Agent: Mozilla/4.1 (compatible; MSIE 6.0; Windows 2000)\n\n";

my @sites=(
    'www.perl.com',
    'www.helsinki.ru',
    'www.cpan.org'
);

foreach my $se (@sites){

    my $socket = IO::Socket::INET->new(
            Type=>SOCK_STREAM,
        PeerAddr => $se,
            PeerPort => 80,
        Proto => 'tcp',
            Blocking => 0,               # This line is very important
          Timeout => 20 
        ) or die "socket $@\n";

    push @sockets,$socket;

}                           

my $i=0;

my $select=IO::Select->new;

for (@sockets)
{ 
    #print "mas: $_\n";
    
    print "request $i \n";

    syswrite($sockets[$i], "GET / HTTP/1.0\nHost: $sites[$i]\n".$blank);

    print "select handle $i \n";
    $select->add($sockets[$i]);
    $i++;
}

$i=0;

while(1){
    if (@ready_read=$select->can_read(0)){# вот здесь не знаю как правильно считать строки. 
         while (defined($ready_read[0])){   
        $strings[$i] = sysreadline(pop(@ready_read),20); # читаю получаю билеберду. 
        $i++;                                              
        }
            
    }
    last if $i == scalar(@sockets);
}

print scalar(@strings);
for (@strings)
{
  print $_."\n";
}  
exit 0;

Короче кто знает как правильно читать из кучи не блокирующихся хедлов массива @ready_read? line  93:   if (@ready_read=$select->can_read(0)){ из этого !

Автор: stan777 13.4.2007, 18:53
Вроде так сделал что-то начало читать, но как бы мне тперь выходить из этого цикла. 

Код

my $line;

while(1)
{
    while(@ready=$select->can_read(0)){

        for (@ready) {
            $line=sysreadline($_);
            print $line;
             }
    }

} 

Автор: KSURi 13.4.2007, 19:33
last добавь после вложенного while

Автор: stan777 15.4.2007, 21:31
Цитата(KSURi @ 13.4.2007,  19:33)
last добавь после вложенного while

Last, если что smile ? last if ???; Просто не могу сам для себя определить критерий выхода из безусловного цикла.

Автор: KSURi 15.4.2007, 21:54
Код

my $line;
while(1)
{
    while(@ready=$select->can_read(0)){
        for (@ready) {
            $line=sysreadline($_);
            print $line;
             }
    }
    last;
} 

Когда can_read вернет false - все закончится

Автор: stan777 15.4.2007, 22:04
Цитата(KSURi @  15.4.2007,  21:54 Найти цитируемый пост)
Когда can_read вернет false - все закончится 

Дело в том что мне can_read() сначала возвращает false, потом начинает возвращать true, но если я там пославлю last то ссоответсвенно выдет сразу, хотя пока я это писал пришла идея перед can_read() поставить sleep(1), хотя задержка в секунду конечно долго.  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)