in reply to A suicidal parent OR death of a forking server

'Tis easy with threads:

#! perl -slw use strict; use threads; use threads::shared; use IO::Socket; use constant CRLF => chr( 13 ) . chr( 10 ); my $server = IO::Socket::INET->new( LocalHost => 'localhost', LocalPort => '7070', Proto => 'tcp', Listen => 5, Reuse => 1, ) or die "Couldn't create listening socket"; my $running :shared = 0; $/ = $\ = CRLF; while( 1 ) { my $client = $server->accept; print "running: $running"; close( $client ), next if $running >= 5; print "Accepted connection from $client"; async { { lock $running; ++$running;} print "$client running"; while( ( my $input = <$client> ) ne 'quit' . CRLF ) { chomp $input; if( $input eq 'printhelp' ) { print $client 'Some help' . CRLF; } elsif( $input eq 'cmd1' ) { print $client 'CMD1 stuff' . CRLF; } elsif( $input eq 'cmd2' ) { print $client 'CMD2 stuff' . CRLF; } elsif( $input eq 'cmd3' ) { print $client 'CMD3 stuff' . CRLF; } else { print $client "Unrecognised command; '$input'" . CRLF; } } lock $running; --$running; print "$client done"; }->detach; } close $server;

That really is the complete program to satisfy your specs. Though you might want to add a signal handler to clean up a little when interupted.

It easier than fork because you can use shared memory to count how many concurrent clients you have without getting into the complexities of IPC.

It's better than select because: a) you don't have to get into writing your own line handling; b) if one of those commands takes 1/2 hour to complete, the whole server doesn't grind to a halt.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"I'd rather go naked than blow up my ass"

Replies are listed 'Best First'.
Re^2: A suicidal parent OR death of a forking server (Use threads)
by MonkeyMonk (Sexton) on Feb 11, 2010 at 11:07 UTC

    Many thanks! Please see my reply to the original post.

    I think I will have to eventually look at what you have written. I am yet to fully explore the drawbacks of the forking.

Re^2: A suicidal parent OR death of a forking server (Use threads)
by observer111 (Novice) on Feb 22, 2010 at 06:59 UTC
    That is the cleanest example IO::Socket::INET server I have seen yet. Nicely done.

      Thanks. It does have limitations thought. Specifically, it will only handle low 10s of concurrent connections before memory becomes an issue. And even if you keep within those levels of concurrency, if the connections are short-lived and made at high speed, it will be CPU-expensive.

      But for the OPs low concurrency, long-lived connections application, it is remarkably simple and stable.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        Thanks for the info, which is good to know. I'm using a server based on your example above to control a pool of threads (using Thread::Pool::Simple) with perl 5.10.1, and don't need much concurrency etc., with this controller at least. I'm just hoping this will play nice with Thread::Pool::Simple. Thread::Pool::Simple tested fine with no leakage warnings... About to find out, I reckon.