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

I've got a script that telnets to a number of network devices using Net::Telnet (well, actually Net::Telnet::Cisco, but this question should still apply), logs into them, runs some commands, parses the output etc.

I'm finding that as of a week ago, I'm intermittantly getting my TCP connection reset by one particular host half way through the command output (I receive approx 120K of output before the RST is sent).

I'm not sure why the connection is being reset, but it would be sufficient if I can detect this situation and attempt to reconnect.

The problem though is that I can't figure out how to tell if the connection is closed or not. In the case of a closed connection, the handle is still valid (as there could be buffered unreaed input waiting), so I can't test on that. Using $t->eof(), I can tell if there is output pending, but I can't spot anything that will tell me if the connection is still valid or not, other than by testing a write and seeing if it suceeds, which seems a bit kludgy to me.

Is there something I'm missing, or do I have to test for a successful write ?

  • Comment on Net::Telnet - how to detect a reset connection ?

Replies are listed 'Best First'.
Re: Net::Telnet - how to detect a reset connection ?
by markh (Scribe) on Dec 12, 2006 at 23:39 UTC
    It appears that using errmode you can specify code to run (i.e. a routine to reconnect) if an error condition is detected.


    reading perldoc Net::Telnet says this about errmode

    errmode - define action to be performed on error

       $mode = $obj->errmode;

       $prev = $obj->errmode($mode);

    This method gets or sets the action used when errors are encountered using the object. The first calling sequence returns the current error mode. The second calling sequence sets it to $mode and returns the previous mode. Valid values for $mode are "die" (the default), "return", a coderef, or an arrayref.
Re: Net::Telnet - how to detect a reset connection ?
by traveler (Parson) on Dec 12, 2006 at 22:24 UTC
    The get and getline methods invoke the behavior specified in errmode, IIRC, so you might be able to use that.
      The most promising option I've found is that errmsg() gets set to 'Connection reset by peer' when the connection has been reset... but it's not ideal because I have to do a string comparison, and there may be other values of errmsg that require a reconnection to recover that I don't know about yet.

      I think what I'm looking for is something like $t->alive() or $t->ping() that returned 0 or 1 based on whether the tcp connection was open not.

Re: Net::Telnet - how to detect a reset connection ?
by vladdrak (Monk) on Dec 13, 2006 at 08:35 UTC
    I've run into this same issue and resolved by wrapping calls in an eval block, like below. This only works on *NIX boxes though -- Windows doesn't support signals per se.
    my $timeout = 20; my $result = eval { local $SIG{ALRM} = sub { die "timed out\n" }; alarm $timeout; my $result = send_command(); alarm 0; return $result; }; if ($@) { print "command timed out\n"; do_something_else(); }