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

Исходное сообщение
"tcp сервер на основе селектов"

Отправлено Almight , 31-Мрт-03 08:55 
Прветствую всех!! народ помогите разобраться...
Вот пробл: пишу сервер на основе селектов.. но убитый юзером сокет приводит к отсановке работы сарвера, в серверах на основе ветлений это значение на имело т.к. смерть потомка не как не влияло на работу родителя.. родитель подолжал порождеть потомков, ну как быть в случаи селектов? ведь юзеры обслуживаются единым процессом :(((
Дело в том что я пишу чат.. с непрерывным коннектом...

Содержание

Сообщения в этом обсуждении
"tcp сервер на основе селектов"
Отправлено Max Zinal , 31-Мрт-03 22:07 
Глупый вопрос: а SIGHUP словить ломает?

"tcp сервер на основе селектов"
Отправлено Almight , 01-Апр-03 07:02 
>Глупый вопрос: а SIGHUP словить ломает?

Хмм... а это есть что такое?


"tcp сервер на основе селектов"
Отправлено Max Zinal , 01-Апр-03 19:11 
>>Глупый вопрос: а SIGHUP словить ломает?
  Вопрос был действительно глупый. SIGPIPE ловить надо
>
>Хмм... а это есть что такое?
  man signal

Вкратце: когда клиент рвёт соединение, сервер получает
для обработки милый такой сигнальчик под названием
SIGPIPE. Действие по умолчанию для него - прервать
процесс сервера, что при обработке нескольких
клиентов есть сущее безобразие. Нужно выставить
свой обработчик. IMHO, разумеется.


"tcp сервер на основе селектов"
Отправлено Almight , 02-Апр-03 07:56 
>Вкратце: когда клиент рвёт соединение, сервер получает
>для обработки милый такой сигнальчик под названием
>SIGPIPE. Действие по умолчанию для него - прервать
>процесс сервера, что при обработке нескольких
>клиентов есть сущее безобразие. Нужно выставить
>свой обработчик. IMHO, разумеется.


foreach $client ($select->can_read(1)){
$client->recv($inbuffer{$client}, POSIX::BUFSIZ, 0);
........... }
............
foreach $client ($select->can_write(1)){
$client->send($outbuffer{$client}, POSIX::BUFSIZ, 0)

if (0){ #в случаи SIGPIPE клиен автоматически удалится?
# или всеже этот код нужно выпролнить после того как
#будет получен SIGPIPE ?
delete $inbuffer{$client};
delete $outbuffer{$client};
$select->remove($client);
close $client;
}}
Вот что интересно.. без $SIG{PIPE} = 'IGNORE';
т.е. $SIG{PIPE} пока негде не учитываю.

При обрыве коннекта, сервак циклется на
foreach $client ($select->can_read(1)){
т.е. сервак не умират, а считает что из сокета можно читать
вот это я не могу понять..



"tcp сервер на основе селектов"
Отправлено Максим Мороз , 02-Апр-03 12:41 
>При обрыве коннекта, сервак циклется на
>foreach $client ($select->can_read(1)){
>т.е. сервак не умират, а считает что из сокета можно читать
>вот это я не могу понять..

Когда клиент закрывает соединение со своей стороны, на сокет становится доступным для чтения.
Попытавшись прочитать оттуда получаешь 0 байт. Если read вернул 0 байт - значит другая сторона закрыла соединение и нам нужно удалить сокет из select-а и закрыть соединение со своей стороны.


"tcp сервер на основе селектов"
Отправлено Almight , 02-Апр-03 13:04 
>Когда клиент закрывает соединение со своей стороны, на сокет становится доступным для
>чтения.
>Попытавшись прочитать оттуда получаешь 0 байт. Если read вернул 0 байт -
>значит другая сторона закрыла соединение и нам нужно удалить сокет из
>select-а и закрыть соединение со своей стороны.

хмм.. а как все это себя поведет в случаи временной потерии
связи с клиентом? что в данном случаи можно считать
timeout`ом ? и как его устанивать?
и что есть $select->has_exception(0) ?

P.S.
Я уже наверно достал всех своими тупыми вопросами
Но к сожалению у меня нет особого выбора
работы много а времени мало.