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.
>
>