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

Исходное сообщение
"запись в 'мертвый' сокет или смерть http сервера"

Отправлено Almight , 25-Июн-03 07:31 
Приветствую!

Написал 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


Содержание

Сообщения в этом обсуждении
"запись в 'мертвый' сокет или смерть http сервера"
Отправлено Almight , 25-Июн-03 13:39 
Проблема решина, тема закрыта!

--
BeZt RegardZ,
    .Almight*, hims[0x7fELF] ;)


"запись в 'мертвый' сокет или смерть http сервера"
Отправлено procool , 25-Июн-03 20:17 
Я просто обрабатываю такую ошибку, да и все.
попробуй eval { }

eval {$rv = $client->send($outbuffer{$client}, 0);}
if  ($@) {
  print "Жопа! $@";
  ## очитска буфера
} else {
ok
}


"запись в 'мертвый' сокет или смерть http сервера"
Отправлено Almight , 28-Июн-03 08:14 
>Я просто обрабатываю такую ошибку, да и все.
>попробуй eval { }
>
> eval {$rv = $client->send($outbuffer{$client}, 0);}
>if  ($@) {
>  print "Жопа! $@";
>  ## очитска буфера
>} else {
> ok
>}

Не здесь баг сидел...
не на send`е ошибка, а на peerhost`е, а
при идентификации другого конца сокета когда того и в помине уже нет..

И в чем кайф просто обрабатывать ошибку?
разве не интересно копнуть поглубже и понять саму суть?