В общем проблемка такая. Скрипт:
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 секунды и закрывать сокет, а не ждать вечно?
1. Использовать неблокирующее чтение
2. Использовать select, последнее особенно полезно, если обрабатываете сразу несколько асинхронных соединений.
>1. Использовать неблокирующее чтение
>2. Использовать select, последнее особенно полезно, если обрабатываете сразу несколько асинхронных соединений.
>А можно конкретнее по этим двум пунктам?
>А можно конкретнее по этим двум пунктам?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 => 5А опции точно case insensitive?
В документации написано Timeout, а не TimeOut.
>> TimeOut => 5
>
>А опции точно case insensitive?
>В документации написано Timeout, а не TimeOut.Что за case insensitive опции?
>>> TimeOut => 5
>>
>>А опции точно case insensitive?
>>В документации написано Timeout, а не TimeOut.
>
>Что за case insensitive опции?Зависящие от регистра символов.
>>>> TimeOut => 5
>>>
>>>А опции точно case insensitive?
>>>В документации написано Timeout, а не TimeOut.
>>
>>Что за case insensitive опции?
>
>Зависящие от регистра символов.Сенк, только Timeout тоже не решает проблему..
>В общем проблемка такая. Скрипт:
>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
>В общем проблемка такая. Скрипт:
>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 ); # уборка зомби
}
##############################################