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

Reply via email to