免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2025 | 回复: 0
打印 上一主题 下一主题

实现多线程并发Telnet管理交换机的两种方法 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2018-12-28 09:14 |只看该作者 |倒序浏览
本帖最后由 liudashang 于 2019-03-16 09:58 编辑

use strict;
use threads;
use Thread::Semaphore;
use Net::Telnet::Cisco;

my $start = time();

my @host = ("192.168.0.2","192.168.0.3","192.168.0.4","192.168.0.5","192.168.0.6");

my @threads;
my $count = 0;

my $signal = Thread::Semaphore->new();                  #测试同步时,请注释掉此行

for my $host (@host) {
    $threads[$count] = threads->create(\&switch,$host); #测试同步时,请注释掉此行
    $count++;                                           #测试同步时,请注释掉此行
    #&switch($host); #测试同步时,请去掉注释!!!
}

for my $th (@threads) {                                 #测试同步时,请注释掉此行
    $th->join();                                        #测试同步时,请注释掉此行
}                                                       #测试同步时,请注释掉此行

my $endtime = time() - $start;
print "\n$endtime\n";

sub switch{
    my $host = shift;
    my $s = Net::Telnet::Cisco->new($host);
    $s->login(Name => 'cisco',Password => 'cisco');
    my @output = $s->cmd('show version');
    $signal->down();                                    #测试同步时,请注释掉此行
    print '*#*' x 30;
    print @output;
    print '=&=' x 30;
    $signal->up();                                      #测试同步时,请注释掉此行
    $s->close;
}

=========================另一种方法======================
使用coro:
use IO::Socket::Telnet;
use strict;
use AnyEvent;
use Coro;
use Coro::AnyEvent;
use Coro::Socket;

my $start = time;

my @host = ("192.168.1.112","192.168.1.113","192.168.1.114","192.168.1.115","192.168.1.116",
            "192.168.1.117","192.168.1.118",,"192.168.1.253","192.168.1.119","192.168.1.120","192.168.1.121",
            "192.168.1.122","192.168.1.123","192.168.1.124","192.168.1.125","192.168.1.126",
            "192.168.1.127","192.168.1.128","192.168.1.129","192.168.1.130","192.168.1.131");
my @coro;


for my $host (@host) { #此处到foreach循环结束都可以照搬照抄
    push @coro, async {
        my $socket = Coro::Socket->new_from_fh
                        (IO::Socket::Telnet->new(
                                 PeerAddr => $host,
                                 Timeout => 5
                            )
                        );
        &doit($host,$socket); #具体多线程操作均在此方法内
        return;
    }
}

foreach (@coro) {
    print "joining\n"; #验证多线程使用,可以删除
    $_->join;
    print "joined\n"; #验证多线程使用,可以删除
}

sub doit {
    my $result; #负责收集telnet服务端返回的信息
    my $host = shift;
    my $socket = shift;
    my $s;
    eval {$s = &read($socket);}; #IO::Socket::Telnet模块本身缺少异常处理,此处
                                 #eval的作用是检测服务器连接超时并报错。考虑到多
                                 #线程,不建议调用die中断程序
    return print "Can't connect $host\n" if $@;
    $result .= $s;
    if ($s =~ /Username:/) { #猜测交换机的telnet密码
        $socket->send("user\n");
        $s = &waitfor($socket,'Password: $');
        $result .= $s;
        $socket->send("password\n");
    } else {
        $socket->send("password\n");
    }
    $s = &waitfor($socket,'.+>$');
=pod
    $result .= $s;
    $socket->send("sh int status\n");
    $s = &read($socket);
    $result .= $s;
=cut

    $socket->send("sh cdp nei de\n");
    $s = &read($socket);
    $result .= $s;

    print $result."\n";

=pod
while (1) {
    my $buffer;
    $socket->send(scalar <>);
    print &read($socket);
}
=cut

    $socket->close;
}

print time-$start;

sub read {  #对recv封装,实现serve回传数据的正常交互
    my $self = shift;
    my $start;
    while (1) {
        $self->recv(my $x, 4096);

        next if !$x;

        $start .= $x;

        last if $x =~ /(<.+>|\[.+\]|.+>|.+#)$/;
        $self->send(' ') if $x =~ /More/;
        last if $x =~ /(Password: ?|Username: ?)/;
    }   

    return $start;
}

sub waitfor { #简单模仿Net::Telnet中的waitfor方法
    my $self = shift;
    my $regx = shift;
    my $start;
    while (1) {
        $self->recv(my $x, 4096);

        next if !$x;

        $start .= $x;

        last if $x =~ /$regx/;
        $self->send(' ') if $x =~ /More/;
    }   

    return $start;
}


您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP