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";
}