http://qs1969.pair.com?node_id=160059


in reply to Activeperl 5.6 fork() doesn't friggin work

Are you sure you need fork for this? Why not just do something like:

#!/usr/bin/perl # Pseudo-Perl; some code shortened to ellipses or text. use IO::Socket; my $sock = IO::Socket::INET->new(...) or die "..."; while (not yet done) # Not sure how you want to determine this { my $line; print $sock "send this to server\n"; chomp($line = <$sock>); #<process $line (one line read from server's response)> } __END__

Also note that

$fork_errlvl = 1 unless defined $pid; die "Error forking client: Reason: $!\n" if $fork_errlvl != 0;

can be shortened to

die "..." unless defined $pid;

or, better IMHO,

defined($pid) or die "..."

both of which eliminate the unnecessary variable.

Replies are listed 'Best First'.
Re: Re: Activeperl 5.6 fork() doesn't friggin work
by Anonymous Monk on Apr 18, 2002 at 01:12 UTC
    This code does work, but it's assuming the client has to write to the server, and then the server replies. While this is generally the case, it's ALSO possible for the server to write to the client without first receiving any information. For example, the client could send the server "data:foo", then the server responds "received". If that was all the information the server needed to complete the operation, it would then respond saying whether the task completed successfully or not. The reason I was forking is so that I have a persistant child listening for whatever the server said.

      Ah. I gathered from your original post (assuming you are jtx) that it was always client, server in strict alternation. If that's not the case, you might be able to use select to determine whether there is data waiting to be read. I believe POE can do this sort of stuff relatively easily, though it may well be overkill.

        What I have been able to do, though it is a cheap hack and will probably have to be re-written if I want this to be a serious program, is taken your idea of using a while loop and somewhat modifying the server/client. This is the modified client, and it works, though like I said, I think it's pretty cheesy:
        #!/usr/bin/perl use IO::Socket; # Make our connections my $ns1 = new IO::Socket::INET (PeerAddr => 'ns1', PeerPort => 1200, Proto => 'tcp' ) or die "Couldn't create socket: $!\n" +; my $line; my $count = 0; my $domain = 'hello.com'; my $ipaddress = '192.168.0.1'; while ($line ne 'CAIO') { if ($count == 0) { print $ns1 "HELO\n"; $count++; } elsif ($count == 1) { print $ns1 "dom:$domain\n"; $count++; } elsif ($count == 2) { print $ns1 "ipaddr:$ipaddress\n"; $count++; } elsif ($count == 3) { print $ns1 "addzone\n"; $count++; } sleep(1); chomp($line = <$ns1>); print "$line\n"; } close($ns1);
        As you might have gathered, the server is a name server, and this program was created to add zones via sockets. It's irrelevant to me at this point whether or not BIND supports this natively - This is just a good way for me to practice using Sockets and TK, and make my boss happy while I write programs that will eventually end up being my replacement :)