Я просматриваю документы и инструкции по правильному использованию IO :: Select с точки зрения сетевых сокетов. Я думаю, что моя голова обернута вокруг большей части.
Тем не менее, я все еще не совсем уверен в правильной обработке ошибок. Скажем, у меня есть нечто похожее на следующий код, работающий внутри объекта. Да, я понимаю, что это грязно, я должен интегрировать IO :: Select в объект, а не в сам сокет fh, я не должен воссоздавать IO :: Select каждый раз в цикле, я перебираю то, что только когда-либо быть единичным возвращаемым дескриптором файла и т. д. Однако это делает пример простым.
Это просто клиент, подключающийся к серверу, но я хочу, чтобы он мог правильно обрабатывать ошибки сетевого уровня, такие как потеря пакетов.
Редактировать: $self->sock()
возвращает только открытый сокет IO :: Socket :: INET.
sub read {
my $self = shift;
my($length) = @_; ### Number of bytes to read from the socket
my $ret;
while (length($ret) < $length) {
my $str;
use IO::Select;
my $sel = IO::Select->new($self->sock());
if (my @ready = $sel->can_read(5)) { ### 5 sec timeout
for my $fh (@ready) {
my $recv_ret = $fh->recv($str, $length - length($ret));
if (!defined $recv_ret) {
MyApp::Exception->throw(
message => "connection closed by remote host: $!",
);
}
}
}
else {
### Nothing ready... we timed out!
MyApp::Exception->throw(
message => "no response from remote host",
);
}
$ret .= $str;
}
return $ret;
}
- Нужно ли проверять возврат из recv, или ошибки, которые могут повлиять на него, будут обнаруживаться в объекте IO :: Select?
- Правильно ли я обращаюсь с таймаутами или неправильно настроена логика?
- IO :: Socket упоминает об исключении, существующем в дескрипторе файла сокета, для внешних ошибок и других проблем. Должен ли я проверить это в случае тайм-аута? Как? Или это неважно и нормально игнорировать?
- Существуют ли другие случаи исключений, которые я должен обрабатывать для правильного поведения?