in reply to Daemon with Net::Daemon

This was discussed quite recently in node 286340. You may find some good answer's there.

Looking at what you are saying, server B needs to be able to run commands on server A. You may find that something like rsh, ssh is the tool for the job. However, if it's something like 'server B connects, get's result of a defined commmand' then you're fairly safe in perl.
If you have some way for the webserver to send the command it requires to server A, then consider very carefully security implications - a daemon that just accepts remote commands and runs them can be an extremely dangerous thing.
In order to create the connection, then the module you want may be Net::Telnet. Or you could do it the slightly harder way by using IO::Socket (but you'll learn more)

IMHO forking 'just because it needs to be parallel' is ugly, and the wrong answer. A 'fork', should be used in situations that you need to create an identical copy of the process. In most daemon examples I've seen, you don't.

I know the perl cookbook recommends doing it this way, but I don't agree. I think the right way to do it (at least with a simple sort of 'do stuff, return result, disconnect' type daemon) is to use IO::Select, thus:

#!/bin/perl use strict; use warnings; use IO::Select; use IO::Socket; #initialise our socket my $listener = IO::Socket::INET -> new( LocalPort => 5001, Proto => "tcp", Reuse => 1, Listen => 20, Blocking => 0, ); $listener -> autoflush(1); #create our 'select' groups my $listen_select = new IO::Select( $listener ); my $sockets = new IO::Select ( ); #A timeout of 0 can be workable, but is inefficient unless #you have _lots_ of IO my $timeout = 1; #seconds; while () { if ( $sockets -> count ) { #check for an incoming socket. Could probably merge #the two can_read statements. if ( $listen_select -> can_read($timeout) ) { my $client; my $raddr = accept($client, $listener); $sockets -> add ( $client ); $client -> autoflush(1); $timeout = 0; print "Connection accepted from ", print unpack ( "C*", $raddr ) +, "\n"; } my @ready = $sockets -> can_read($timeout); #if any socket has pending data, read it and act on it. foreach my $handle ( @ready ) { my $read_tmp = <$handle>; if ( !defined ( $read_tmp ) ) { print "Filehandle closed.\n"; $sockets -> remove ( $handle ); $handle -> close; } else { #do processing here. #imagine doing something good with read_tmp print "Got data: $read_tmp\n"; #and sending something cool to the client print $handle "Fwatoom\n"; } } } #if count else { #we have no handles in our thingy, so we sit idle waiting for #a connection. print "No pending data. Idling for connect()\n"; my $client; my $raddr = accept($client, $listener); $sockets -> add ( $client ); $client -> autoflush(1); $timeout = 0; print "Connection accepted from ", print unpack ( "C*", $raddr ), +"\n"; } }
For the client side, you can do something like:
Note that the two won't _quite_ work together - you'll have to modify one or the other. The server expects an input, and then sends an output, this snippet will simply get all the data it can from the server, and then exit when the connection closes.
#!/bin/perl use strict; use warnings; use IO::Socket; my $destination_port = 5001; #change these how you will my $destination_address = "localhost"; my $socket = new IO::Socket::INET ( proto => "tcp", PeerAddr => $destination_address, PeerPort => $destination_port, ) or die "$!"; #send our "command" to the server print $socket "hello\n"; #See what the response is. In this case, we'll just keep #reading until the socket is closed remotely. while ( <$socket> ) { print; }

Replies are listed 'Best First'.
Re: Re: Daemon with Net::Daemon
by BUU (Prior) on Sep 02, 2003 at 16:42 UTC
    Why do you not like fork for situations like this? To me it seems like the perfect tool to create little child processes. Also although I hate to point out the obvious the 'server' I posted above has maybe five times less code, making it substanially easier to read and write.
      I dislike the idea of duplicating the entire process for something simple like printing a response to the socket. Fork is know as a heavyweight process for a reason. (yes, I know that copy-on-demand alleviates this)

      I also rather like showing off an example of one of the other ways to do it, which becomes useful in some of the situations where a fork is not.

      As ever, there's more than one way to do it. Fork can be effective and simple, but IO::Select allows one some better control over child processes.

      I've never actually profiled the code, but I'd imagine that fork works pretty good on Unix, where it's integral to the OS. (Ish, because it becomes a little fuzzier when you're talking about forking perl, and the interpreted code) I'd not be so sure about doing so on Windows.

      Has anyone tried a benchmark of the relative methods?