See embedded updates below:
jack ciabatta wrote:
Mmhh... I'm trying with threads->exit();.. any suggests? Could be
useful a similar "simple, practical and complete" example on cpan? For
newbies. It would be great.
Regards,
Jack
my $port = 2500;
my $timeout = 60;
$| =1;
my $server = IO::Socket::INET->new (
Proto => 'tcp',
LocalPort => $port,
Listen => SOMAXCONN,
Timeout => $timeout,
ReuseAddr => 1
) or die "Error: can't create listening socket : $!\n";
while (my $client = $server->accept()) {
my $thr = threads->create("listen_to_client", $client);
my $thr1 = threads->create("stdin_to_client", $client);
print "Client connected ", $thr->tid,"\n";
$thr->detach;
$thr1->detach;
#
# is this trip really necessary ?
#
# $thr->detach;
# $thr1->detach;
}
exit(0);
sub listen_to_client {
my ($client) = @_;
my $tid = threads->tid();
while (my $get = <$client>) {
print "client ($tid) : $get";
print $client $get;
};
print "Client closed\n";
close $client;
#
# better to exit a thread with a value
#
return 1;
}
sub stdin_to_client {
my ($client) = @_;
while (my $msg = <STDIN>) {
print $client $msg;
if ($msg =~ /exit/i){
print "exit\n";
close $client if $client;
#
# replace the following:
#
#threads->exit() if threads->can('exit');
threads->exit();
#
# with
#
last;
}
}
print "stdin thread ended\n";
return 1;
}
With all that said, I think you'll find the updated solution
less than satisfactory. Unfortunately, thread startup in Perl
takes a very long time, so spawning a thread for each new socket
connection is probably a bad idea.
So I'd suggest a couple of threads upfront, and an assoc. message queue
to dispatch sockets, e.g., (note: this is not complete, and I'm not
too certain what your app is trying to accomplish, as there are some
issue esp. wrt using the same STDIN for possibly many clients):
use threads;
use Thread::Queue;
my $fromq = Thread::Queue->new();
my $toq = Thread::Queue->new();
my $doneq = Thread::Queue->new();
my $reader = threads->create(\&listen_to_client);
my $writer = threads->create(\&stdin_to_client);
my $port = 2500;
my $timeout = 60;
$| =1;
my $server = IO::Socket::INET->new (
Proto => 'tcp',
LocalPort => $port,
Listen => SOMAXCONN,
Timeout => $timeout,
ReuseAddr => 1
) or die "Error: can't create listening socket : $!\n";
while (my $client = $server->accept()) {
$fromq->enqueue(fileno($client));
$toq->enqueue(fileno($client));
print "Client connected \n";
$done = $doneq->dequeue;
# probably more stuff here to untangle this mess
}
sub listen_to_client {
my $tid = threads->tid();
while (1) {
my $fd = $fromq->dequeue;
last if $fd eq 'STOP';
open my $client, '+>>&=', $fd;
while (my $get = <$client>) {
print "client ($tid) : $get";
print $client $get;
};
print "Client closed\n";
close $client;
$doneq->enqueue('CLIENT DONE');
}
return 1;
}
sub stdin_to_client {
while (1) {
my $fd = $toq->dequeue;
last if $fd eq 'STOP';
open my $client, '+>>&=', $fd;
while (my $msg = <STDIN>) {
print $client $msg;
if ($msg =~ /exit/i) {
print "exit\n";
close $client;
$doneq->enqueue('STDIN DONE');
last;
}
}
print "stdin thread ended\n";
}
return 1;
}
HTH,
Dean Arnold
Presicient Corp.