Задать вопрос

Вопрос к PERL программистам

Есть perl демон:

#!/usr/bin/perl -w
###Подключение всех необходимых модулей###
use strict;
use POSIX;
use POSIX ":sys_wait_h";
use IO::Socket;
use IO::Handle;
###Создаем процесс-демон###
my $pid= fork();
exit() if $pid;
die "Couldn't fork: $! " unless defined($pid);
###Создаем связь с новым терминалом###
POSIX::setsid() or die "Can't start a new session $!";
###Переменная - бесконечное время жизни сервера###
my $time_to_die =0;
###Переменная - интернет-сокет или сервер###
my $server;
###Функция обработчик сигналов INT и TERM###
###Она срабатывает перед этими сигналами###
sub signal_handler{
  $time_to_die = 1;
  close($server);
}
$SIG{INT}= $SIG{TERM} = $SIG{HUP} = \&signal_handler;

###Функция обработчик сигнала CHLD - для уборки процессов зомби ###
sub REAPER {
  while ((my $waitedpid = waitpid(-1,WNOHANG)) > 0) { }
  $SIG{CHLD} = \&REAPER;
}

###Заполняем массив разрешенных команд при старте сервера###

###Создаем интернет сокет на порту 17403###
my $server_port=17403;
$server= new IO::Socket::INET(LocalPort => $server_port,
                 TYPE => SOCK_STREAM,
                 Reuse => 1,
                 Listen => 10)
or die "Couldn't be a tcp server on port $server_port: $@\n";
###Сервер работает до бесконечности пока его не вырубит Term ###
until($time_to_die){
  my $client;
  my $req;
  ###Обрабатываем входящие подключения
  while($client = $server->accept()){
    ###Включаем обработку зомби###
    $SIG{CHLD} = \&REAPER;
    ###Тот который постучался, отделяем в отдельный процесс###
    defined(my $child_pid=fork()) or die "Can't fork new child $!";
    ###Родительский процесс идет в конец и ждет следующего подключения###
    next if $child_pid;
    ###Дочернему процессу копия сокета не нужна, её закрываем###
    if($child_pid == 0) {
      close($server);
    }
    ###Очистка буфера###
    $client->autoflush(1);
    my $response = <$client>;
    my @get_req = split(' ', $response);
    print $client $get_req[1];
  exit;
  }
  continue {
    close($client);
  }

}


* This source code was highlighted with Source Code Highlighter.


Данный демон запускается и слушает указанный порт, и при запросе к нему скажем через браузер.
sitename.ru:17403/?param=1&param2=2
он создаст процесс свою копию, обработает запрос этим процессом и отдаст клиенту "/?param=1&param2=2". После этого закроет этот процесс.

Вопрос в том, всё ли правильно написано и всё ли правильно я понимаю и главное будет ли это работать так как я описал?
  • Вопрос задан
  • 2943 просмотра
Подписаться 5 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 3
Нет, неправильно. Браузер посылает серверу не просто строку, а HTTP-запрос, состоящий из нескольких строк. Пока все их не прочитаешь, браузер входящие данные принимать не начнёт, а в приведённом коде считывается только первая строка запроса.

Кстати, избавиться от зомбей можно проще:
$SIG{CHLD} = 'IGNORE';

И ещё: если после демонизации происходит ошибка, то выдача сообщения может выглядеть весьма необычно (от терминала-то отвязались). Правильнее пользоваться системным логом или вести свой лог-файл.
Ответ написан
Комментировать
iSage
@iSage
Что только не делают люди, лишь бы не использовать AnyEvent.
Ответ написан
Комментировать
Legion
@Legion Автор вопроса
Значит у меня как то не так работает
поскольку код:

my $response = <$client>;
print $client $response;

при запросе sitename.ru:17403/?param=1¶m2=2
отвечает мне
GET /?param=1¶m2=2 HTTP/1.1
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы