M
M
Michael2011-02-21 10:37:47
Perl
Michael, 2011-02-21 10:37:47

Question for PERL programmers

There is a perl daemon:

#!/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: [email protected]\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.


This daemon starts and listens on the specified port, and when requested to it, let's say through the browser.
sitename.ru :17403/?param=1¶m2=2
it will create a copy of itself, process the request by this process and return "/?param=1¶m2=2" to the client. After that, it will close this process.

The question is, is everything written correctly and do I understand everything correctly, and most importantly, will it work as I described?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
K
Konstantin Vlasov, 2011-02-21
@CaptainFlint

No, it's wrong. The browser sends the server not just a string, but an HTTP request consisting of several lines. Until you read all of them, the browser will not start accepting incoming data, and in the code above, only the first line of the query is read.
By the way, getting rid of zombies can be easier:

$SIG{CHLD} = 'IGNORE';

And one more thing: if an error occurs after daemonization, then the output of a message may look very unusual (they got rid of the terminal). It is better to use the system log or keep your own log file.

I
Ivan, 2011-02-22
@iSage

What people don't do to avoid using AnyEvent .

M
Michael, 2011-02-21
@Legion

It means that somehow it doesn’t work for me
because the code:
my $response = <$client>;
print $client $response;
when requesting sitename.ru :17403/?param=1¶m2=2
it answers me with
GET /?param=1¶m2=2 HTTP/1.1

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question