java实现telnet登录

背景

有些老的小型机是没有ssh登录,只有telnet登录的方式,由于监控的要求,需要登录设备执行脚本拿到数据,那么telnet稳定登录就是必不可少的一步了。

telnet登录的过程

监听XXX的意思是等待输入的数据匹配后面的正则表达式,在控制台登录时,输出telent登录时会等待系统返回指引信息,所以根据指引信息来输出账号密码,这里的输出指的是往输出流写数据,输入指的是输入流输入的数据。流程如下
telnet登录流程图

commons-net介绍

apache开源的commons-net实现了一系列网络协议,包括不限于telnet,echo,ftp,nntp等,在这里我们可以利用它协助我们进行telnet登录。

使用方式,通过maven引入

<dependency>
    <groupId>commons-net</groupId>
    <artifactId>commons-net</artifactId>
    <version>3.8.0</version>
</dependency>

交互式实现登录

首先在登录前我们需要有一个组件来帮助我们管理输入输出流,并且能根据我们的需要做一些等待输入的操作,也能方便地输出。前面我已经写了一篇文章来介绍管理输入输出的组件,请参考该文章java优雅地管理输入输出流_芜湖启飞的博客-CSDN博客

具体的登录代码如下

创建连接

public HostConnection connect(Host host) throws Exception {
        //termType 字体
        TelnetClient telnetClient = new TelnetClient("VT220");
        telnetClient.setConnectTimeout(10000);
        telnetClient.setDefaultTimeout(30000);
        try {
            //登录第一个节点
            HostConnectionNode firstHostConnectionNode = host.getNodeList().get(0);
            telnetClient.connect(firstHostConnectionNode.getAddress(), firstHostConnectionNode.getPort());
        } catch (Exception e) {
            telnetClient.disconnect();
            throw new ConnectionException("端口不通");
        }

        return new TelnetHostConnection(host, telnetClient);
    }

此时还仅仅是建立了telnet连接,还没有进行账号密码的验证,接下来的代码就是进行账密的交互验证,,验证流程图可以往上面翻

		ExchangeObserver exchangeObserver = streamExchange.getExchangeObserver();
        FinishOneExchangeListener finishOneExchangeListener = new FinishOneExchangeListener();
        exchangeObserver.register(finishOneExchangeListener);

        String outStr;
        try {
            finishOneExchangeListener.refreshPattern("[L|l]ogin:");
            finishOneExchangeListener.await(15, TimeUnit.SECONDS);
            streamExchange.reset();

            finishOneExchangeListener.refreshPattern("[P|p]assword:");
            streamExchange.write(connectionNode.getUsername());
            finishOneExchangeListener.await(15, TimeUnit.SECONDS);
            streamExchange.reset();

            finishOneExchangeListener.refreshPredict(StrUtil::isNotBlank);
            streamExchange.write(connectionNode.getPassword());
            finishOneExchangeListener.await(15, TimeUnit.SECONDS);

            outStr = streamExchange.getPrintContent();
            if (ReUtil.contains(loginFailPattern, outStr)) {
                throw new ConnectionException("登录节点[%s]失败,错误信息%s".formatted(connectionNode.toString(), outStr));
            }
            //如果执行换行命令返回为空字符串的话则认定为登录失败
            finishOneExchangeListener.refreshPredict(StrUtil::isNotBlank);
            streamExchange.write(" ");
            finishOneExchangeListener.await(1, TimeUnit.SECONDS);

            outStr = streamExchange.getPrintContent();
            //校验返回的文本来判定是否登录成功
            return checkLoginMsg(connectionNode, outStr);
        } catch (TimeoutException timeoutException) {
            throw new ConnectionException("登录节点[%s]失败,错误信息%s".formatted(connectionNode.toString(), streamExchange.getPrintContent()));
        }

以上代码都可以在开源项目中找到,指路–>shixinmuhuo/PowerExec: PowerExec是一个超强的支持无限跳板的远程执行脚本的工具。致力于解决重复繁琐的手工运维问题。 (github.com)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值