LINUX.ORG.RU

[perl] почему так медленно читается сокет?

 


0

0

Здравствуйте. Я в перле новичок, так что сильно не пинайте, если глупость спрошу :)
Чтение данных с сокета происходит, но как-то очень медленно -
гораздо медленнее, чем я, скажем, введу этот адрес в браузере и дождусь загрузки странички.
Почему так происходит? Вот кусок кода:

...
socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
print "connecting to $host ... ";
connect(SOCK, $paddr);
print "OK\n";

print "sending GET to /dollar-$mth-$nyear.html ... ";
send (SOCK, "GET /dollar-$mth-$nyear.html HTTP/1.1\nHost: $host\n\n", 0);
print "OK\n";

my @data = <SOCK>;
...

★★

вот пример эхо сервера :
сервер :
use strict;
use Socket;
use IO::Handle;
use constant MY_ECHO_PORT => 2007;

my ($bytes_out,$bytes_in) = (0,0);

my $port     = shift || MY_ECHO_PORT;
my $protocol = getprotobyname('tcp');

$SIG{'INT'} = sub { 
    print STDERR "bytes_sent = $bytes_out, bytes_received = $bytes_in\n";
    exit 0;
};

socket(SOCK, AF_INET, SOCK_STREAM, $protocol) or die "socket() failed: $!";
setsockopt(SOCK,SOL_SOCKET,SO_REUSEADDR,1)    or die "Can't set SO_REUSADDR: $!" ;

my $my_addr = sockaddr_in($port,INADDR_ANY);
bind(SOCK,$my_addr)    or die "bind() failed: $!";
listen(SOCK,SOMAXCONN) or die "listen() failed: $!";

warn "waiting for incoming connections on port $port...\n";

while (1) {
  next unless my $remote_addr = accept(SESSION,SOCK);
  my ($port,$hisaddr) = sockaddr_in($remote_addr);
  warn "Connection from [",inet_ntoa($hisaddr),",$port]\n";

  SESSION->autoflush(1);
  while (<SESSION>) {
    $bytes_in  += length($_);       
    chomp;
    my $msg_out = (scalar reverse $_) . "\n";
    print SESSION $msg_out;
    $bytes_out += length($msg_out);
  }
  warn "Connection from [",inet_ntoa($hisaddr),",$port] finished\n";
  close SESSION;

}

close SOCK;


клиент - запускать с параметром - хост , порт :
use strict;
use Socket;
use IO::Handle;
my ($bytes_out,$bytes_in) = (0,0);

my $host = shift || 'localhost';
my $port = shift || getservbyname('echo','tcp');

my $protocol = getprotobyname('tcp');
$host = inet_aton($host) or die "$host: unknown host";

socket(SOCK, AF_INET, SOCK_STREAM, $protocol) or die "socket() failed: $!";
my $dest_addr = sockaddr_in($port,$host);
connect(SOCK,$dest_addr) or die "connect() failed: $!";

SOCK->autoflush(1);

while (my $msg_out = <>) {
    print SOCK $msg_out;
    my $msg_in = <SOCK>;
    print $msg_in;

    $bytes_out += length($msg_out);
    $bytes_in  += length($msg_in);
}

close SOCK;
print STDERR "bytes_sent = $bytes_out, bytes_received = $bytes_in\n";

набираем в клиенте строку и тут же получаем ответ
вроде ниче не тормозит

kto_tama ★★★★★
()
Ответ на: комментарий от kto_tama

Спасибо - посмотрю, поковыряюсь... а почему мой вариант тормозит есть догадки?

lv ★★
() автор топика

HTTP/1.1 - видимо тут получается keep-alive соединение, сервер сам не закрывает сокет после отдачи данных, а ждет некоторое время что ему в этот же сокет еще запросы придут, а my @data = <SOCK>; продолжает висеть на чтении. добавь Connection: close, а вообще LWP лучше использовать. ответ лучше читать в переменную, а не массив

PoMbl4
()
Ответ на: комментарий от PoMbl4

Спасибо. Попробовал HTTP 1.0 - всё сработало гораздо быстрее.

lv ★★
() автор топика
Ответ на: комментарий от PoMbl4

Посмотрел на LWP - хорошая библиотечка - спасибо за совет. Да и вообще - perl - это очень хорошо - не перестаёт меня радовать :)

lv ★★
() автор топика
Ответ на: комментарий от dilmah

> дьявол умеет соблазнять
попытка развязать флейм? :) А чего в перле такого неправославного?

lv ★★
() автор топика
Ответ на: комментарий от lv

> попытка развязать флейм? :) А чего в перле такого неправославного?
1) Отсутствие работоспособных потоков.
2) Крайне ненадежная обработка сигналов.
3) Некоторые врапперы на системные вещи обладают отличной 
семантикой (что просто очень неудобно).

Perl прекрасный язык для своих задач.
Но писать на нем системные вещи (особенно сетевые демоны) это просто
ужас.

Krivenok_Dmitry
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.