现在的位置: 首页 > 综合 > 正文

An easy way to track state of network connection using Perl

2013年07月02日 ⁄ 综合 ⁄ 共 2665字 ⁄ 字号 评论关闭

Tonight,  just paste some code here. I'll comment these code when I'm free.

https://gist.github.com/3305055

8/11/2012 Update


Background

Unix Shell can be timed out after setting a environment variable TMOUT, I want to verify if this feature is implemented correctly on my system. so I create a scenario that connect to remote server through Telnet, and issue TMOUT=xx after logging on to Shell,
then issue command "netstat -na"  repeatedly  to observe if the telnet is available that 's in 'established' state as below. 

TCP    xx.xx.xx.xx:62453    yy.yy.yy.yy:23
     ESTABLISHED

Obviously, it's a tedious work to check connection state manually. 

Solution

As a lazy man, I wrote a Perl script to complete this task automatically ^_^.  Here I just used a common module Net::Telnet. Other things like regex, grep, qx, split are built-in functions and syntax in Perl.  

At first, save a snapshot of telnet connections into a array @conns_old. Thanks to qx and grep syntax, I can do it  just in a line.

my@conns_old=grep{/:23\s+/}qx(netstat
-na)
;

Then, connect to Unix server through Telnet. Need to invoke some interface introduced by Net::Telnet.

my$t=Net::Telnet->new(Timeout=>60,

                          Prompt=>'/#|>|&/');

$t->open($hostname);

$t->login($username,$password)ordie"Failed
to connect"
;

my@conns_new=grep{/:23\s+/}qx(netstat
-na)
;

After logging on to Shell successfully, capture Telnet connections(text) again, here we get a new array.

my@conns_new=grep{/:23\s+/}qx(netstat
-na)
;

Finally, just compare these two arrays @conns_old and @conns_new. The connection exists in the new array but not in the old array would be the new one created just now.

my($conn)=grep{!defined$existed{$_}}@conns_new; 

 What's the left thing is to check state of the new one again and again util it turns to other states TIME_WAIT, CLOSE_WAITor CLOSED. BTW, as a Perl newbie, I indeed love this syntactic sugar, split/\s+/,$conn)[4],
Perl guys are all lazy men.


Discussion

I know you may say my implementation is not good that's not exactly and effectively, and it's better to invoke some socket API ... Yes, that's true,
this is not the best way, but should be an easy way, just right so I can complete my work without overwork :)


use Net::Telnet;
use strict;


my $hostname = 'xxx';
my $username = "xx";
my $password = "xx";
my @conns_old = grep { /:23\s+/ } qx(netstat -na);
my %existed = map { $_ => 1 } @conns_old;

foreach(@conns_old)
{
    print "$_\n";
}

my $t = Net::Telnet->new( Timeout => 60,
                           Prompt => '/#|>|&/');
print "Connect to $hostname\n";

$t->open($hostname);
$t->login($username, $password) or die "Failed to connect";

my $cmd_logs = q(TMOUT=60);
my $str = $t->cmd($cmd_logs);


my @conns_new = grep { /:23\s+/ } qx(netstat -na);
foreach(@conns_new)
{
    print "$_\n";
}

my ($conn) = grep { !defined $existed{$_} } @conns_new;


my $cnt = 0;
while((split /\s+/, $conn)[4] eq "ESTABLISHED")
{
    ++$cnt;
    print "${cnt}: $conn\n";
    sleep 1;
    
    @conns_new = grep { /:23\s+/ } qx(netstat -na);
    my $token = (split /\s+/, $conn)[3];
    ($conn) = grep { /$token/ } @conns_new;
}


$t->close;

抱歉!评论已关闭.