mmh... but if the client send an "exit" the connection remains active, why? :(
# telnet 127.0.0.1 2500 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. hi exit EXIT 2007/11/14, Dean Arnold <[EMAIL PROTECTED]>: > 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. > >