Help with a program

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

I am a perl newbie working on a program.  I have two problems (Code
and design to follow):

1) The program works fine, unless two connections are made at the same
time, if two connections are made, both sessions are handled
correctly, but once both complete, the parent dies as well.  I do not
know what.

2) I now can write to the socket, but I need to do a read from the
socket, I do not know how to do that.

Here is the design:

I am a newbie perl programmer and I have an idea for a perl program,
but I want to know if it is possible before I attempt to write it.
Here is what I need:

I have a client, talking to my server via TCP/IP to port 1234.  The
client is creating many seperate conversations that are a simple
request/response pairing. All requests from the client go to port
1234.  Here is how I would like it to flow:

(main loop) accepts connection on port 1234 ->
locks port 1234 from any other new connection ->
redirects conversation to lesser know port (ex. 2345) ->
calls on port 2345 to handle request response

as soon as fires off ->
unblock port 1234 and allow another connection  (main loop)-> handles all communications with client and upon
completion (or time out) imports that port 2345 is avilabile
for communication and then dies (or optionally wait for to
send another session to it).

Here is the code so far:

#!/usr/bin/perl -Tw
use strict;
BEGIN { $ENV = '/usr/ucb:/bin' }
use Socket;
use Carp;
my $CRLF = "52";

sub spawn;  # forward declaration
sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" }

my $port = shift || 6666;
my $proto = getprotobyname('tcp');

($port) = $port =~ /^(\d+)$/                        or die "invalid

socket(Server, PF_INET, SOCK_STREAM, $proto)    || die "socket: $!";
setsockopt(Server, SOL_SOCKET, SO_REUSEADDR,
                                        pack("l", 1))   || die
"setsockopt: $!";
bind(Server, sockaddr_in($port, INADDR_ANY))    || die "bind: $!";
#listen(Server,4)                               || die "listen: $!";
listen(Server,SOMAXCONN)                                || die
"listen: $!";

logmsg "server started on port $port";

my $waitedpid = 0;
my $paddr;

use POSIX ":sys_wait_h";
   sub REAPER {
      my $child;
      while (($waitedpid = waitpid(-1,WNOHANG)) > 0) {
         logmsg "reaped $waitedpid" . ($? ? " with exit $?" : '');
   $SIG = \&REAPER;  # loathe sysV


for ( $waitedpid = 0;
  ($paddr = accept(Client,Server)) || $waitedpid;
  $waitedpid = 0, close Client)
next if $waitedpid and not $paddr;
my($port,$iaddr) = sockaddr_in($paddr);
my $name = gethostbyaddr($iaddr,AF_INET);

logmsg "connection from $name [",
        inet_ntoa($iaddr), "]
        at port $port";

spawn sub {
my $counter=1;
#my $etx="";

while ($counter<10){
print "testing $counter $CRLF";
sleep 1;
$counter=$counter + 1;
print "ba-bye\n";


sub spawn {
my $coderef = shift;

unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') {
    confess "usage: spawn CODEREF";

my $pid;
if (!defined($pid = fork)) {
    logmsg "cannot fork: $!";
} elsif ($pid) {
    logmsg "begat $pid";
    return; # I'm the parent
# else I'm the child -- go spawn

open(STDIN,  "<&Client")   || die "can't dup client to stdin";
open(STDOUT, ">&Client")   || die "can't dup client to stdout";
## open(STDERR, ">&STDOUT") || die "can't dup stdout to stderr";
exit &$coderef();

Site Timeline