Here is the parred down code and where the error occurs:
use strict;
use IO::Socket;
use threads;
use threads::shared;
my $numClients = shift;
my %thread_status : shared;
my $server_status : shared = 'threading';
$| = 1;
my $screen_output : shared = 1;
my $HOST = 'cdt-2x4w227x';
my $PORT = 7001;
# Launch clients in their own thread
print "Creating $numClients clients\n";
for (my $i=0; $i<$numClients; $i++) {
my ($retries,$socket);
$socket = IO::Socket::INET->new("$HOST:$PORT") || print "Socket cr
+eation error: $!\n";
while (!$socket) {
print "Retrying socket connection for client $i\n";
$retries++;
if ($retries > 5) {
print "Exceeded retries while launching client $i\n";
last;
}
sleep 1;
$socket = IO::Socket::INET->new("$HOST:$PORT") || print "Socke
+t creation error on retry $retries: $!\n";
}
if ($socket) { my $t = threads->new(\&handle_client,$socket,$i)->d
+etach } else { print " Error creating socket: $i\n" }
print ".";
}
print "Done creating clients\n";
sleep 1;
$server_status = 'ready';
print "Waiting for client threads to finish\n";
while (my @keys = keys %thread_status) {
my $count = @keys;
print &time_stamp," Waiting for [$count] threads from [@keys]\n";
sleep 1;
}
sleep 1;
#<------------------------------------------------------------ handle_
+client -->
sub handle_client {
my ($socket,$clientNum) = @_;
my $line;
my $tid = threads->self->tid;
my $timeout = 2;
$thread_status{$clientNum} = $clientNum;
while ($server_status eq 'threading') { sleep 1 }
#VINI
print " $clientNum -> VINI\n" unless (!$screen_output);
if ($socket) { $socket->send("VINI\n") || $socket->close && undef
+$socket && return }
^^^^^^ FAILS ON SEND ^^^^^^^
$line = <$socket> if ($socket);
print " $clientNum <- $line" unless (!$screen_output);
sleep rand($timeout);
lock %thread_status;
delete $thread_status{$clientNum};
$socket->close;
threads->self->yield;
return;
}
Error is: thread failed to start: Can't call method "send" without a package or object reference at thread_test.pl line 60
So it looks like you're right about the timeout. So how would one handle and recover from such a time out? Thanks! | [reply] [d/l] |
I chopped down your code quite a bit, and also created a multi-threading server. I tried with 100 socket, and don’t see any problem.
Failed to go 200, the problem is low virtual memory, any way, the code itself works.
server.pl:
use IO::Socket::INET;
use threads;
use strict;
my $server = new IO::Socket::INET(Proto => "tcp", LocalPort => 7001, L
+isten => 5)
|| die "failed to establish socket\n";
while (1) {
my $client = $server->accept;
threads->create(\&client_handle, $client);
}
sub client_handle {
my $client = shift;
while (1) {
my $line = <$client>;
chomp $line;
print $client $line + 1, "\n";
}
}
client.pl:
use strict;
use IO::Socket;
use threads;
use threads::shared;
my $numClients = shift;
my %thread_status : shared;
my $server_status : shared = 'threading';
$| = 1;
print "Creating $numClients clients\n";
for (my $i=0; $i<$numClients; $i++) {
my $socket = IO::Socket::INET->new(Proto => "tcp", PeerAddr => "lo
+calhost", PeerPort => 7001) || print "Socket creation error: $!\n";
threads->new(\&handle_client,$socket,$i)->detach;
print ".";
}
print "\nAll Created\n";
sleep 1;
$server_status = 'ready';
<STDIN>;
#<------------------------------------------------------------ handle_
+client -->
sub handle_client {
my ($socket,$clientNum) = @_;
while ($server_status eq 'threading') { sleep 1 }
print $socket "1\n";
while (1) {
my $line = <$socket>;
chomp $line;
print "$clientNum <<== $line\n";
print $socket $line + 1, "\n";
sleep 1;
}
return;
}
| [reply] [d/l] |