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

Исходное сообщение
"accept() - многопоточность не пошла :("

Отправлено exec , 05-Ноя-05 20:02 
#!/usr/bin/perl
use IO::Socket;

$port=4141;
$bind=IO::Socket::INET->new(Listen=>5,LocalPort=>$port);

$client=$bind->accept();
$client->send("Тру-ля-ля");

$client2=$bind->accept();
$client2->send("Ля-ля-тру");

close($client);
close($client2);
close($bind);


Насколько я понимаю, алгоритм должен работать так:
1. Открыли сокетку;
2. Ждём соединения;
3. При первом соединении приняли его и передали открывающей стороне "Тру-ля-ля";
4. Держим первое соединение открытым и ждём второго соединения;
5. Дождались второго соединения, передали открывающей стороне "Ля-ля-тру";
6. Прикрыли все соединения и ждущую сокетку, вышли.

На деле всё работает так:
1. Открыли сокетку;
2. Ждём соединения;
3. Приняли первое соединение и передали туда "Тру-ля-ля";
4. Стоим колом пока прицепившаяся сторона не закроет первое соединение;
5. Ждём второго соединения;
6. Дождались, передали "Ля-ля-тру";
7. Прикрыли всё, вышли.

Подскажите заставить всё работать с двумя одновременно открытыми соединениями?

Собственно задача моя проста - написать многопоочный сервер, который мог бы держать несколько соединений одновременно, при этом не нагружая сервер по самое "мама не горюй".

Нашел какие-то исходники в сети, где было в общих чертах так:

#!/usr/bin/perl
use IO::Socket;

$SIG{CHLD}='IGNORE';

$port=4141;
$bind=IO::Socket::INET->new(Listen=>5,LocalPort=>$port);

while ($client=$bind->accept()){

$pid = fork();
unless(defined($pid)){close($bind); exit;}
if ($pid){
close($client);
}else{
$client->send("Тру-ля-ля");
sleep(100); # подразумеваются некие действия с открытым соединением
close($client);
exit;
}

} # while ($client=$bind->accept())

Вот только проблема точно такая, то есть после первого accept() пока не закрыто первое соединение, второе соединение не аццептиться, accept() просто висит и ждёт пока прикроют первое соединение.

Подскажите чем смазать лыжи, что бы ехать?
Или плиз покажите код (ссылку на код) скрипта, который есть многопоточный tcp сервер (а не сервер, который последовательно обрабатывает все приходящие соединения (таких в сети полно видел)).


Содержание

Сообщения в этом обсуждении
"accept() - многопоточность не пошла :("
Отправлено jd , 05-Ноя-05 22:50 
У меня ваш код работает нормально.
Рекомендую делать перед закрытием сокета shutdown (это к данному вопросу не относится).

"accept() - многопоточность не пошла :("
Отправлено ACCA , 06-Ноя-05 00:04 
>закрыто первое соединение, второе соединение не аццептиться, accept() просто висит и
>ждёт пока прикроют первое соединение.

В Windows так и должно быть - у него fork нету. Если у тебя *nix, то проверь лимиты - сколько ещё процессов ты имеешь право создать?


>Или плиз покажите код (ссылку на код) скрипта, который есть многопоточный tcp
>сервер (а не сервер, который последовательно обрабатывает все приходящие

Твой кусок - нормальный многопоточный сервер. На каждое соединение он создаёт процесс с помощью fork и потом каждый процесс работает с клиентом.


"accept() - многопоточность не пошла :("
Отправлено rWizard , 06-Ноя-05 07:33 
в дополнение - обратите внимание на модуль IO::NonBlocking
позволяет создать tcp сервер, обрабатывающий множество соединений в одном потоке

"accept() - многопоточность не пошла :("
Отправлено exec , 07-Ноя-05 03:46 
Господа, уверен, будете смеяться.
Проверял те коды что привёл здесь на домашней ЭВМ (linux RH) - не работало... Загрузил на сервер, работает на ура.
Перекачал с cpan  на домашний ЭВМ и переставил модуль IO::Socket всё заработало.
Вот так иногда бывает, что на диске с дистрибутивом линуха был кривой модуль...
Честное слово, если бы не подсказали что код рабочий, с ума бы сошел в поисках вкопаной в алгоритм собаки.