http://www.perlmonks.org?node_id=164934

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Heya, Monks. When I began using the Net::Telnet module to write a MU* bot, I used the following procedure: I created a while loop which on every iteration checked for the previous line, like this:
$line = $telnet->getline(Timeout=>1000000);

I used the long Timeout obviously so that it wouldn't time out. The problem came when I added another connection. Now, it won't getline from one of the connections until it has recieved a new line from the other. Here's the entire program, currently:

#Use the telnet module use Net::Telnet; #Variables my $dbl; my $rwl; my $person; #And now, define all the servers we're going to use: $darkblade = new Net::Telnet (Timeout=>10, Errmode=>'die', Port=>7575) +; $redwall = new Net::Telnet (Timeout=>10, Errmode=>'die', Port=>4203); #Here we actually connect: print "Now connected to Darkblade...\n"; $darkblade->open('darkblade.2y.net'); sleep(2); print "Now logged into Darkblade as Boteille.\n"; $darkblade->print('connect boteille abc123'); print "Now connected to Redwall...\n"; $redwall->open('redwall.muck.limitless.org'); sleep(2); print "Now logged into Redwall as Scava.\n"; $redwall->print('connect scava abc123'); #Now start a while() loop to listen for input... BREAK: while(1) { #this is the variable new lines in Darkblade will be stored in: $dbl = $darkblade->getline(Timeout=>1000000); #And the same sort of thing for Redwall... $rwl = $redwall->getline(Timeout=>1000000); #Avoid idle boots in Darkblade: if ($dbl =~ 'The rains are approaching...') { $darkblade->print('dshf'); } if ($dbl =~ '2 mins before auto idleboot.') { $darkblade->print('dshf'); } #And also in Redwall... if ($rwl =~ 'IDLE-BOOT: You will be dropped in 5 minutes.') { $redwall->print('dshf'); } #And now we get to the first use... if someone asks for help if($dbl =~ /pages, "help"/) { ($person) = $dbl =~ /^(\w+)/; $darkblade->print("page $person=Boteille currently supports..."); $darkblade->print("page $person=-- This help page"); } if($rwl =~ /pages, "help"/) { ($person) = $rwl =~ /^(\w+)/; $redwall->print("page $person=Scava currently supports..."); $redwall->print("page $person=-- This help page"); } }


Is there a more efficient way of doing this, or a way to bypass this problem?

Replies are listed 'Best First'.
Re: Net::Telnet problems
by hatter (Pilgrim) on May 08, 2002 at 10:28 UTC
    If you read for input with zero timeout, and then only try and process the data if there's anything to be processed, then the loop will run through both options, regardless of whether there's data on both inputs or not. Don't forget to add in something to stop it looping at high speed, though, or it'll eat all your CPU while it's not doing anything.

    An alternative solution is to fork off a process for each tcp connection you're making, as you don't appear to be doing any cross communication between the two in your example code. That way you can wait indefinately on input still.

    the hatter

      If I read for input with zero timeout, the program immediately quits, saying: read timed-out at bot.pl line 29

      I can't use a different process, because I intend to include cross communication in the future.

      Thanks,
      Anonymous Monk