http://www.perlmonks.org?node_id=165373

Gorby has asked for the wisdom of the Perl Monks concerning the following question:

Hello wise monks. I need to write code that will stay connected to another server continuously 24x7. Will the following code do the job? Or should I use infinite loops? If so, how?
use IO::Socket; use strict; my $socket; my $line; my $child_pid; $socket = IO::Socket::INET->new ( PeerAddr => 'server.com', PeerPort => 1247, Proto => "tcp", Type => SOCK_STREAM ) or die "Could not create client.\n"; unless (defined($child_pid = fork())) {die "Cannot fork.\n"}; if ($child_pid) { while($line = <>) { #here I'm gonna make the server read some files and #throw stuff to the other socket } } else { while ($line = <$socket>) { #here I'm gonna make the server listen for stuff from #the other socket. The information that comes from this #connection will be store in files that will be accessed #by the parent process. Is this gonna work? 24x7? #Non-stop? } }
Thanks

Replies are listed 'Best First'.
Re: Need Help with Sockets, Please
by broquaint (Abbot) on May 09, 2002 at 14:19 UTC
    If the socket closes at the other end (e.g server shuts down), then the while loop will end and the child will exit. So you may want to wrap your socket read loop within another loop that will open the socket e.g
    while($some_guaranteed_condition) { my $socket = IO::Socket::INET->new( ... ); while($line = <$socket>) { ... } $socket->shutdown(2); }
    This should loop until the silicon wears out, but you'll probably want to put in some graceful shutdown mechanism within the first loop (and the second loop perhaps?). I'd also check out CPAN for some daemon type modules (e.g Net::Daemon and Net::TCP::Server).
    HTH

    _________
    broquaint

Re: Need Help with Sockets, Please
by ferrency (Deacon) on May 09, 2002 at 14:19 UTC
    The code you wrote looks to me like it'll work only as long as the connection created in your IO::Socket::INET command stays up. If a network outage occurs, if the remote end closes the connection, or if the person or script sending input to your script via STDIN closes the pipe, then one of your while() loops will finish and the corresponding process will die.

    Also: as it is now, if your child dies (remote connection close) but your STDIN keeps coming, the parent process will live on indefinitely, but it won't work very well.

    You could try to wrap the entire thing in a while (1) loop, but that wouldn't fix the problem of one process living on once the other exits. One way to fix this is to make sure the parent process is the one which exits its loop most often, and then to have it kill off its child process after the loop exits, since it knows its child's pid.

    Without seeing what you're doing in the while loops it's hard to tell whether this is the best way to do what you want. Be aware that after you fork(), you can't share new variable values between the parent and child processes. Your idea to share data through files can work, but beware of deadlock.

    Alan

Re: Need Help with Sockets, Please
by ozone (Friar) on May 09, 2002 at 14:24 UTC

    Well, if you're lucky it may stay connected for a while, but you definitely need to check for $line being undefined, and then re-establish the connection. Otherwise your program will terminate when the socket closes.

    You should take a look for POE on CPAN. It's built for exactly this kind of scenario. Bit of a learning curve though.

    Also, you need to make sure you do a 'wait' (or define $SIG{SIG_CHLD}) somewhere, otherwhise you'll have problems if the child crashes for some reason!

If you have some $$$
by Rex(Wrecks) (Curate) on May 09, 2002 at 17:14 UTC
    If you don't mind spending a few bucks, I would also recomend Network Programming with Perl, it has many examples of what you are doing as well as giving an understanding to Daemonization and a pletora of other network related programming skills and tips.

    "Nothing is sure but death and taxes" I say combine the two and its death to all taxes!