如何在Perl中创建TCP服务器守护进程?

时间:2009-10-05 08:59:57

标签: perl

我希望在Perl中创建一个TCP服务器守护进程。

哪个是最好的框架/模块?。

Perl捆绑了什么?

修改:已启动的内容停止|重启选项会很棒。

编辑:它必须是多线程服务器。

6 个答案:

答案 0 :(得分:4)

嗯 - 如果你能说明这个守护进程应该做什么,那就更好了。因为有各种任务的专门框架/库。

对于什么也不做的最简单的守护进程,只要存在,你就可以轻松地做到这一点:

#!/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服务器。

行。这是简单的代码:

#!/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 - 它变得更加复杂,你必须问自己是否更喜欢多线程(或多处理),或者你更喜欢单进程,基于事件的服务器。

答案 1 :(得分:2)

您实际上并不想编写多线程perl。 Perl线程被破坏 - 它们无法正常工作(在我看来)。

创建一个新的perl线程克隆整个解释器,包括当前在范围内的所有数据 - 因此基本上比创建一个新进程(当然,它将使用copy-on-write)更糟糕而且不太有用。

所以你绝对不希望它多线程。

答案 2 :(得分:2)

如果可能,我会考虑将AnyEvent作为纯线程方法的替代方案。

答案 3 :(得分:1)

我自己从来没有机会尝试过,但我相信POE在这方面受到高度重视。

以下是some examples of TCP servers written with POE.

答案 4 :(得分:0)

  

“开始|停止|重启选项的东西会很棒”

CPAN上有模块可以提供此功能。例如,我可以看到Daemon::Generic声称是框架,为守护进程提供启动/停止/重新加载

/ I3az /

答案 5 :(得分:0)

A quick search揭示了很多可能性。 Daemon::Generic似乎很容易使用。

此外,还有许多用于各种协议的服务器模块。实际上,HTTP::Daemon已成为一段时间的核心模块。