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

Howdy again, :-)

This time I'm having difficulty controlling the timeout when initializing a Net::Telnet session. I set Timeout to 1, I've also set -timeout to 1. However, the the constructor is taking between 20 and 30 seconds before it times out and returns to the code. I need to bring this down to 2 seconds or less. Is there any way to make this call abort if it is not successfull within 1 or 2 seconds?

Note that I am only having this problem in Windows. On the mac, the timeout works just fine.

OS: Windows 7 Enterprise
Version 6.1 (Build 7601: Service Pack 1)

PERL: v5.16.3 built for MSWin32-x86-multi-thread

#!/usr/bin/perl # use strict; use warnings; use Net::Telnet; my $host = '192.168.130.112'; # valid host that is offline my $port = 10001; print "DEBUG 1\n"; my $t = new Net::Telnet (Host => $host, Port => $port, Timeout => 1, # -timeout => 1, Prompt => '/Escape character is.+\n/', Rs => ' ', Ors => '', Binmode => 1, Telnetmode => 1, Errmode => 'return'); print "DEBUG 2\n"; if (!$t) { die "Failed to create telnet session\n"; }

Replies are listed 'Best First'.
Re: Timeout parameter for Net::Telnet under Windows
by VinsWorldcom (Prior) on Jan 22, 2016 at 15:36 UTC

    A quick bit of debugging with the Net::Telnet module shows you're getting hung up on line 1563:

    connect $self, $remote_addr or die "problem connecting to \"$host\", port $port: $!\n";

    I looked at 'perldoc Socket' and found the connect() routing but nothing glaring about 'blocking' or 'timeout' or something to that effect. Not sure why the alarm() around the connect() in Net::Telnet isn't having the proper affect.

    Sorry no solution, but hopefully that points you (or someone smarter than me) in the right direction?

      On Windows, alarm() doesn't interrupt system calls, so that's maybe why the timeout isn't working properly.

        I've logged a bug for this at https://rt.cpan.org/Public/Bug/Display.html?id=111370 with this info. Hopefully somebody can come up with a fix or a workaround. I'm having to write some ugly code to get around this in the meantime.

        As I said above "someone smarter than me" - thanks for coming to the rescue Corion!

        I just found and tried this code, still no luck. It still takes 20 to 30 seconds to regain control. From Chapter 18. The UDP Protocol, in "Network Programming with Perl".

        eval { local $SIG{ALRM} = sub { die "timeout\n" }; alarm(2); $t = new Net::Telnet (Host => $host, Port => $port, Timeout => 1, Prompt => '/Escape character is.+\n/', Rs => ' ', Ors => '', Binmode => 1, Telnetmode => 1, Errmode => 'return'); alarm(0); }; if ($@) { die $@ unless $@ eq "timeout\n"; warn "Timed out!\n"; }
Re: Timeout parameter for Net::Telnet under Windows
by Anonymous Monk on Jan 22, 2016 at 17:13 UTC

    Well, this is silly. Net::Telnet wants to time out with alarm(), although IO::Socket has a better method — non-blocking connect — that ought to work on Windows, too.

    Perhaps you could try to outsmart the Net::Telnet? Create your object sans Host/Timeout; connect with open() instead. Then slip a sneaky $t->SUPER::timeout(1); before the open. Just an idea...

      Ok, so I tried this. But I don't know exactly how to pull it off.

      I took the Host out of the new() constructor so that the constructor would not call open(), and added these lines of code:

      289 t->{Host} = $host; 290 t->SUPER::timeout(1); 291 t->open();
      I get this error:
      Error: Not a HASH reference at line test.pl line 289.

        I haven't tried this on Windows yet so your mileage may vary.

        #!/bin/env perl use strict; use warnings; use Net::Telnet; my $host = '192.168.130.112'; # valid host that is offline my $port = 10001; print "DEBUG 1\n"; my $t = new Net::Telnet ( Port => $port, Prompt => '/Escape character is.+\n/', Rs => ' ', Ors => '', Binmode => 1, Telnetmode => 1, Errmode => 'return'); print "DEBUG 2\n"; if (!$t) { die "Failed to create telnet object\n"; } $t->open(Host => $host, Timeout => 1) or die "Failed to create telnet session\n";
Re: Timeout parameter for Net::Telnet under Windows
by RonW (Parson) on Jan 26, 2016 at 00:00 UTC

    Maybe use IO::Socket to make the connection then the Fhopen option on Net::Telnet::new to establish the Telnet session:

    my $s = IO::Socket::INET::new(PeerHost => $host, PeerPort => $port, Blocking => 0, ...); my $t = Net::Telnet::new(fhopen => $s, ...);

    Disclaimer: Not tested. YMMV

Re: Timeout parameter for Net::Telnet under Windows
by Mr. Muskrat (Canon) on Jan 28, 2016 at 21:53 UTC

      I set TcpMaxDataRetransmissions to 1 and TCPInitialRtt to 0x12c (the minimum allowed), and rebooted the Windows 7 Enterprise. No affect whatsoever. It still takes 20 to 30 seconds before timing out.

      Thanks though for the lead.