URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 7079
[ Назад ]

Исходное сообщение
"Timeout on perl socket udp"

Отправлено DemonShi , 31-Дек-07 01:04 
В общем проблемка такая. Скрипт:
my $socket = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => 'udp', TimeOut => 5 );
syswrite $socket, "\xFF\xFF\xFF\xFFTSource Engine Query\x00";
sysread $socket, $buffer, 96;
close $socket;
отсылает по протоколу удп запрос на сервак контры, потом кидает полученное в переменную $buffer, но если пакет не дойдет то скрипта, то он зависает.. Таймаут в сокетах не помогает :( Как можно его заставить ждать например 2 секунды и закрывать сокет, а не ждать вечно?

Содержание

Сообщения в этом обсуждении
"Timeout on perl socket udp"
Отправлено angra , 31-Дек-07 04:27 
1. Использовать неблокирующее чтение
2. Использовать select, последнее особенно полезно, если обрабатываете сразу несколько асинхронных соединений.

"Timeout on perl socket udp"
Отправлено DemonShi , 31-Дек-07 15:20 
>1. Использовать неблокирующее чтение
>2. Использовать select, последнее особенно полезно, если обрабатываете сразу несколько асинхронных соединений.
>

А можно конкретнее по этим двум пунктам?


"Timeout on perl socket udp"
Отправлено angra , 03-Янв-08 10:41 
>А можно конкретнее по этим двум пунктам?

1. Использовать неблокирующее чтение.
Для большинства операций ввода/вывода Perl предоставляет вариант неблокирующего чтения. Если мы его используем, то вызов read/sysread приводит к мгновенному возврату управления в программу. Для того чтобы определить действительно ли было что-то считано проверяем возвращенное значение. Обычно функция чтения помещается в цикл и проверяется ее значение и еще какие-либо условия. Выбор между блокирующим/неблокирующим режимом обычно осуществляется в момент открытия хендлера. В вашем случае смотрим perldoc IO::Socket::INET и находим следующий параметр:
Blocking    Determine if connection will be blocking mode
If "Blocking" is set to 0, the connection will be in nonblocking mode.  If not specified it defaults to 1 (blocking mode).

2. Использовать select
Тут не так все просто. Стоит вдумчиво почитать man и посмотреть несколько примеров кода, первое что вспоминается Net::DNS::Async.


"Timeout on perl socket udp"
Отправлено Michelnok , 31-Дек-07 18:06 
> TimeOut => 5

А опции точно case insensitive?
В документации написано Timeout, а не TimeOut.


"Timeout on perl socket udp"
Отправлено DemonShi , 31-Дек-07 18:52 
>> TimeOut => 5
>
>А опции точно case insensitive?
>В документации написано Timeout, а не TimeOut.

Что за case insensitive опции?


"Timeout on perl socket udp"
Отправлено anonymous , 02-Янв-08 02:40 
>>> TimeOut => 5
>>
>>А опции точно case insensitive?
>>В документации написано Timeout, а не TimeOut.
>
>Что за case insensitive опции?

Зависящие от регистра символов.


"Timeout on perl socket udp"
Отправлено DemonShi , 02-Янв-08 13:06 
>>>> TimeOut => 5
>>>
>>>А опции точно case insensitive?
>>>В документации написано Timeout, а не TimeOut.
>>
>>Что за case insensitive опции?
>
>Зависящие от регистра символов.

Сенк, только Timeout тоже не решает проблему..


"Timeout on perl socket udp"
Отправлено DemonShi , 04-Янв-08 23:00 
>В общем проблемка такая. Скрипт:
>my $socket = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => 'udp', TimeOut => 5 );
>syswrite $socket, "\xFF\xFF\xFF\xFFTSource Engine Query\x00";
>sysread $socket, $buffer, 96;
>close $socket;
>отсылает по протоколу удп запрос на сервак контры, потом кидает полученное в
>переменную $buffer, но если пакет не дойдет то скрипта, то он
>зависает.. Таймаут в сокетах не помогает :( Как можно его заставить
>ждать например 2 секунды и закрывать сокет, а не ждать вечно?
>

Все, мне помогли)) ПРоблема решилась с использованием select


"Timeout on perl socket udp"
Отправлено Nikolai Sokolov , 29-Янв-09 14:42 
>В общем проблемка такая. Скрипт:
>my $socket = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => 'udp', TimeOut => 5 );
>syswrite $socket, "\xFF\xFF\xFF\xFFTSource Engine Query\x00";
>sysread $socket, $buffer, 96;
>close $socket;
>отсылает по протоколу удп запрос на сервак контры, потом кидает полученное в
>переменную $buffer, но если пакет не дойдет то скрипта, то он
>зависает.. Таймаут в сокетах не помогает :( Как можно его заставить
>ждать например 2 секунды и закрывать сокет, а не ждать вечно?
>

# При помощи alarm() . Для мили и наносекунд можно использовать Time::HiRes (www.cpan.org)
##############################################
use Errno qw(EAGAIN);

DUAL_PROC: {

  if ($pid = fork) {
    waitpid($pid,0);
  } elsif (defined $pid) {
   alarm($n);
#
# Код перл прекратит существовать через $n секунд
#
} elsif ($! == EAGAIN ) { print "Процесс ПОВИС"; redo DUAL_PROC; }
   else { die "Ошибка ветвления: $!"; }

  $SIG{CHILD} = sub { 1 } until ( waitpid(-1, WNOHANG) == -1 ); # уборка зомби
              }
##############################################