Как я могу создать процесс демона сервера TCP в Perl? - PullRequest
0 голосов
/ 05 октября 2009

Я хочу создать демон-процесс на TCP-сервере в Perl.

Какой самый лучший фреймворк / модуль для него?.

Есть ли что-нибудь, что поставляется в комплекте с Perl?

Редактировать: То, что имеет начало | остановить | Варианты перезапуска были бы отличными.

Редактировать: Это должен быть многопоточный сервер.

Ответы [ 6 ]

4 голосов
/ 05 октября 2009

Что ж, было бы лучше, если бы вы могли заявить, что должен делать этот демон. Так как существуют специализированные фреймворки / библиотеки для различных задач.

Для простейшего демона, который ничего не делает, просто существует, вы можете легко сделать это:

#!/usr/bin/perl
use strict;
use warnings;
use Carp;
use POSIX qw( setsid );

daemonize();

do_your_daemon_stuff();

exit;

sub daemonize {
    chdir '/'                 or croak "Can't chdir to /: $!";
    open STDIN, '/dev/null'   or croak "Can't read /dev/null: $!";
    open STDOUT, '>/dev/null' or croak "Can't write to /dev/null: $!";
    defined(my $pid = fork)   or croak "Can't fork: $!";
    exit if $pid;
    setsid                    or croak "Can't start a new session: $!";
    open STDERR, '>&STDOUT'   or croak "Can't dup stdout: $!";
}

sub daemonize () был отменен из perldoc perlipc (с незначительными изменениями).

Вот и все - код теперь правильно демонизируется и может делать все, что угодно.

Я только что прочитал вашу правку, что вы хотите TCP-сервер.

OK. Вот упрощенный код:

#!/usr/bin/perl
use strict;
use warnings;
use Carp;
use POSIX qw( setsid );
use IO::Socket;

my $server_port = get_server_port();

daemonize();

handle_connections( $server_port );

exit;

sub daemonize {
    chdir '/'                 or croak "Can't chdir to /: $!";
    open STDIN, '/dev/null'   or croak "Can't read /dev/null: $!";
    open STDOUT, '>/dev/null' or croak "Can't write to /dev/null: $!";
    defined(my $pid = fork)   or croak "Can't fork: $!";
    exit if $pid;
    setsid                    or croak "Can't start a new session: $!";
    open STDERR, '>&STDOUT'   or croak "Can't dup stdout: $!";
}

sub get_server_port {
    my $server = IO::Socket::INET->new(
        'Proto'     => 'tcp',
        'LocalPort' => 31236,
        'Listen'    => SOMAXCONN,
        'Reuse'     => 1,
    );
    die "can't setup server" unless $server;

    return $server;
}

sub handle_connections {
    my $port = shift;
    my $handled = 0;

    while ( my $client = $port->accept() ) {
        $handled++;
        print $client "Hi, you're client #$handled\n";
        chomp ( my $input = <$client> );
        my $output = reverse $input;
        print $client $output, "\n";
        print $client "Bye, bye.\n";
        close $client;
    }

    return;
}

Просто помните, что это блокирует tcp-сервер, поэтому он сможет обрабатывать 1 соединение одновременно. Если вам нужно больше 1 - это становится более сложным, и вы должны спросить себя, предпочитаете ли вы многопоточность (или многопроцессорность), или вы предпочитаете однопроцессный сервер на основе событий.

2 голосов
/ 05 октября 2009

Если возможно, я бы рассмотрел что-то вроде AnyEvent как альтернативу чисто потоковому подходу.

2 голосов
/ 05 октября 2009

Вы на самом деле не хотите писать многопоточный Perl. Потоки Perl не работают - они не работают должным образом (на мой взгляд).

Создание нового потока perl клонирует весь интерпретатор, включая все данные, находящиеся в настоящее время в области видимости, поэтому, в принципе, это ДЕЙСТВИТЕЛЬНО, чем создание нового процесса (который, конечно, будет использовать копирование при записи) и менее полезно.

Так что вы определенно не хотите, чтобы он был многопоточным.

1 голос
/ 05 октября 2009

У меня никогда не было возможности попробовать это самостоятельно, но я считаю, что POE высоко ценится за подобные вещи.

Вот некоторые примеры TCP-серверов, написанных с помощью POE.

0 голосов
/ 05 октября 2009

Быстрый поиск открывает довольно много возможностей. Daemon :: Generic кажется простым в использовании.

Кроме того, существует множество серверных модулей для различных протоколов. Фактически, HTTP :: Daemon уже некоторое время является основным модулем.

0 голосов
/ 05 октября 2009

"То, что имеет параметры start | stop | restart, было бы замечательно"

На CPAN имеются модули, которые обеспечат это. Например, я вижу Daemon :: Generic , который утверждает, что является фреймворком для обеспечения запуска / остановки / перезагрузки для демона .

/ I3az /

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...