Home > front end >  TCP Server using perl fork to accept multiple requests
TCP Server using perl fork to accept multiple requests

Time:08-22

I'm trying to create a little server who handles multiple clients connections (at least 10). Below the current code that works perfect using fork. At least it accepts several connections from clients.

With the below code, I have the following behaviour:

  • Client ask for connection ==> Accepted ==> OK
  • Client sent packet ==> Received and printed ==> OK
  • Client sent another packet ==> Not received ==> NOK

Most probably, the while cicle will be activated only for each connection request, so that's the reason because I cannot retrieve other packets.

Could someone help me please to adjust the below code? What I need is establish one (or more) client connection, then client send data continuosly (without disconnection) and server should reply on each packet it receives.

#!/usr/bin/perl -w
use IO::Socket::INET;

$SIG{CHLD} = sub {wait ()};
my $socket = new IO::Socket::INET (
    LocalHost => '0.0.0.0',
    LocalPort => '5000',
    Proto => 'tcp',
    Listen => 5,
    Reuse => 1);
die "cannot create socket $!n" unless $socket;

while ($new_sock = $socket->accept()) {
   $pid = fork();
   die "Cannot fork: $!" unless defined($pid);

   if ($pid == 0) {     # This is the fork child
      $new_sock->recv(my $data, 500);
      print "$data\n";
   }
}

CodePudding user response:

You need to loop around the recv call to read more than one package from the client. Also, as it's currently written, the SIGCHLD signal interrupts accept so when the first child process dies, your server program terminates. You could just add a loop around the accept loop to restart the accept call.

Example:

#!/usr/bin/perl

use strict;
use warnings;
use IO::Socket::INET;

$SIG{CHLD} = sub { wait; };

my $socket = new IO::Socket::INET (
    LocalHost => '0.0.0.0',
    LocalPort => '5000',
    Proto => 'tcp',
    Listen => 5,
    Reuse => 1);
die "cannot create socket $!n" unless $socket;

sub child {
    my $sock = shift;
    my $data;
    print "$$ connected\n";
    # loop for as long as there's something coming in
    while($sock->recv($data, 500) || $data) {
        print "$$ $data";  # prepend the data with the process id
    }
    print "$$ disconnected\n";
    exit 0;
}

while(1) {
    while (my $new_sock = $socket->accept()) {
        my $pid = fork();
        die "Cannot fork: $!" unless defined($pid);

        if ($pid == 0) {     # This is the fork child
            child($new_sock);
        }
    }
    print "accept interrupted - restarting\n";
}
  •  Tags:  
  • perl
  • Related