Приветствую!
Написал http сервер на perl, вроде работает норм.
Но вот не так давно сталкнулся с багом убивающем сервер.
Примерный код сервера:
while (1) {
foreach $client ($select->can_read(1)) {
if ($client == $server) {
$client = $server->accept();
$select->add($client);
} else {
$rv = $client->recv($data, POSIX::BUFSIZ, 0);
unless (defined($rv) && length $data) {
# Это должен быть конец файла, поэтому закрываем клиента
delete $inbuffer{$client};
delete $outbuffer{$client};
$select->remove($cllent);
close $client;
next;
}
$inburfer{$client} .= $data;
$outbuffer{$client} = handle ($inburfer{$client});
#handle - обработчик запросов
}
}
foreach $client ($select->can_write(1)) {
# Пропустить этого клиента, если нам нечего сказать
next unless exists $outbuffer{$client};
$rv = $client->send($outbuffer{$client}, O):
delete $inbuffer{$client};
delete $outbuffer{$client};
$select->remove($cllent);
close($client);
next;
}
}
Такой сервер можно убить просто зажав F5 в браузере типа IE
получаю ошибку
Bad arg length for Socket::unpack_sockaddr_in, length is 4096, should be 16 at /usr/lib/perl5/i386-linux/Socket.pm line 312.
Подозреваю что выползает оно по причине закрытия сокета
сразу после получения полного http запроса т.е. после вызова handle
но перед циклом foreach $client ($select->can_write(1)) {
а т.к. в $outbuffer{$client} содержится ответ сервер пытаеся
записать их в "мертвый" сокет - это и приводит к смерти сервера
Не знаю правильно ли я понял причину смерти сервера,
но если так, то как поставить проверку на существования сокета
перед циклом foreach $client ($select->can_write(1)) ?
Сам сервер сидит тут chat.asut.ru:2340