2009-10-05 9 views
0

Je souhaite créer un processus démon de serveur TCP en Perl.Comment créer un démon de serveur TCP en Perl?

Quel est le meilleur cadre/module pour cela?

Y a-t-il quelque chose qui est fourni avec Perl?

Editer: Quelque chose qui a commencé | arrêter | les options de redémarrage seraient géniales.

Editer: Il doit s'agir d'un serveur multithread.

+0

Quel type de serveur? Il existe des modules pour implémenter des serveurs HTTP, des serveurs SMTP, ... – cjm

+0

Un simple démon de serveur TCP. – someguy

+0

en double de http://stackoverflow.com/questions/766397 –

Répondre

4

Eh bien, c'est mieux si vous pouviez dire ce que ce démon est supposé faire. Comme il existe des cadres/bibliothèques spécialisés pour diverses tâches.

Pour le démon simple qui ne fait rien, il existe juste, vous pouvez le faire facilement:

#!/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: $!"; 
} 

sous daemonize() a été LIFTEN de perldoc perlipc (avec changement mineur).

C'est tout - le code est maintenant correctement démonisé et peut faire tout ce que vous voulez.

Je viens de lire votre édition, que vous voulez un serveur TCP.

OK. Voici le code simpliste:

#!/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; 
} 

Rappelez-vous simplement que ce bloque serveur tcp, il sera en mesure de gérer 1 connexion à l'époque. Si vous voulez plus de 1 - cela devient plus complexe, et vous devez vous demander si vous préférez le multithreading (ou le multi-traitement), ou si vous préférez un serveur basé sur les événements à un seul processus.

+0

J'écris un démon de serveur TCP. – someguy

+0

Merci pour la réponse. Mais oui, je dois en faire un serveur multi-thread. – someguy

+1

Donc, d'abord - reformulez votre question. Désolé, mais je ne vais pas deviner ce dont vous avez besoin. Pensez à ce dont vous avez besoin, et * essayez * de l'écrire. Je ne vais pas écrire votre code pour vous. –

0

"Quelque chose qui a start | stop | options de redémarrage serait génial"

Il existe des modules sur CPAN qui fourniront cela. Par exemple, je peux voir Daemon::Generic qui prétend être un cadre pour fournir start/stop/recharger pour un démon.

/I3az/

1

Vous ne voulez pas vraiment d'écrire perl multithread. Les threads Perl sont cassés - ils ne fonctionnent pas correctement (à mon avis). La création d'un nouveau thread perl clone l'interpréteur complet, y compris toutes les données actuellement dans la portée. Il est donc fondamentalement pire que de créer un nouveau processus (qui, bien sûr, utiliserait copy-on-write) et moins utile.

Donc, vous ne voulez certainement pas qu'il soit multithread.

+0

Donc, ce que vous suggérez est que l'écriture d'un serveur TCP multi threads en Perl est une mauvaise idée? Mais j'ai lu que le fil de perl sont bien sur v 5.8. – someguy

+0

Les threads Perl fonctionnent correctement avec la mise en garde qu'ils utilisent plus de mémoire et prennent plus de temps à démarrer que de démarrer un processus séparé complet; ils ne peuvent pas partager des variables facilement, le verrouillage est beurk. Fondamentalement, ils ont été mal conçus, ce qui n'est pas réparable sans rupture de compatibilité avec tout programme qui les utilise. – MarkR

1

Si possible, je considérerais quelque chose comme AnyEvent comme une alternative à une approche filetée pure.

0

A quick search révèle un certain nombre de possibilités. Daemon::Generic semble être simple à utiliser.

En outre, il existe de nombreux modules de serveur pour divers protocoles. En fait, HTTP::Daemon a été un module de base pendant un moment maintenant.

Questions connexes