远程连接Telnet

     这是一个远程连接工具,使用的是Apache commons-net.3.3,下面的代码是自己做的封装

    

     maven配置如下:

    

<dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.3</version>
</dependency>
<!--这里是引用了本地的一个jar包,主要服务于WeatherTelnet类-->
<dependency>
            <groupId>commons-net</groupId>
            <artifactId>examples</artifactId>
            <version>3.3</version>
            <scope>system</scope>
            <systemPath>H:\Apache\commons-net\commons-net-examples-3.3.jar</systemPath>
        </dependency>

     封装的Telnet类

package com.special.utils.telnet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.telnet.TelnetClient;

import java.io.*;

/**
 * file TelnetUtil
 * 使用Apache的commons-net 3.3 作为底层,封装的一个远程连接工具包
 * TODO:如果字符串的截取未按理想状态进行,那么程序将挂起,所以最好将byte数组设为一屏的字节
 * @author ds
 * @version 1.0 2015
 *          date 15-3-18
 */
public class TelnetUtil {
    Log log = LogFactory.getLog(TelnetUtil.class);
    /**
     * 终端类型,格式由前缀T_加终端类型构成
     */
    public enum TerminalType {
        T_513, T_715, T_4410, T_4425, T_VT220, T_NTT, T_W2KTT, T_SUNT;

        /**
         * 获取终端类型的类型名称
         *
         * @return 实际类型名称
         */
        public String getTypeName() {
            String name = this.name();
            return name.substring(2, name.length());
        }
    }

    /**
     * 连接失败后,尝试重连的次数 _rCnt作为常量标识
     */
    final Integer _rCnt = 1;
    Integer reCntCount = _rCnt;
    /**
     * 终端输入用户名的提示信息
     */
    final String _logPrompt = "login: ";
    /**
     * 终端输入密码的提示信息
     */
    final String _pwdPrompt = "Password: ";
    /**
     * 终端选择终端类型的提示信息
     */
    final String _terPrompt = "[513]";
    /**
     * 终端输入命令的提示信息
     */
    final String _cmdPrompt = "Command: ";
    /**
     * 客户端
     */
    TelnetClient client;
    /**
     * 终端类型
     */
    String _terName = "W2KTT";
    /**
     * 远程输入流;该处使用过Reader,本来意欲每次读取一行,
     * 但是实验结果表示使用reader导致输出停滞
     */
    InputStream remoteInput;
    /**
     * 远程输出流 ,使用该流主要是使用它的println()功能;
     * 他不需要手动加入回车换行,相当于每输入一次,自动加确认机制
     */
    PrintStream remoteOut;

    /**
     * 构造方法
     *
     * @param host    远程主机域名或者IP
     * @param port    主机的端口号
     * @param terType 终端类型
     */
    public TelnetUtil(String host, Integer port, TerminalType terType) {
        //开启客户端连接
        _terName = terType.getTypeName();
        client = new TelnetClient(_terName);
        //远程连接
        if (getConnect(host, port)) {
            //设置输入输出流
            remoteInput = client.getInputStream();
            remoteOut = new PrintStream(client.getOutputStream());
        } else { //如果连接失败需要初始化流
            remoteInput = new ByteArrayInputStream("connect failure!".getBytes());
            remoteOut = new PrintStream(new ByteArrayOutputStream());
        }
    }

    /**
     * 获取远程连接
     *
     * @param host 主机域名或者IP
     * @param port 主机端口
     * @return boolean true 连接成功 false 连接失败
     */
    private boolean getConnect(String host, Integer port) {
        boolean flag = false;
        try {
            client.connect(host, port);
            flag = true;
        } catch (IOException e) {
            //尝试重复连接,此处可以不使用同步,因为getConnect为私有非静态,并且连接次数也是非静态
            if (!client.isConnected() && reCntCount > 0) {
                reCntCount--;
                if (getConnect(host, port)) {
                    reCntCount = _rCnt;
                    flag = true;
                }
            } else {
                reCntCount = _rCnt;
            }
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 输入用户名、密码登录终端
     *
     * @param name 用户名
     * @param pwd  用户密码
     */
    public void login(String name, String pwd) {
        //输入用户名
        read(_logPrompt);
        write(name);
        //输入密码
        read(_pwdPrompt);
        write(pwd);
        //输入终端信息
        read(_terPrompt);
        write(_terName);
        //读取可以输入命令
        read(_cmdPrompt);
    }

    public StringBuffer execCommand(String command,String endBy){
        write(command);
        return readEndBy(endBy);
    }

    /**
     * 读取流中的数据
     *
     * @param flagWords 流中是否含有该标志
     * @return String 错误则返回error,否则返回读取的字符串
     */
    public String read(String flagWords) {

        String tmp = null;
        int read ;
        byte[] buff = new byte[2048];
        flagWords = flagWords==null?"":flagWords;
        try {
            while ((read = remoteInput.read(buff))>0) {
                tmp = new String(buff,0,read);
                log.info("#" + tmp + "#");
                /*此处就是潜在的BUG,如果截取的字符串非理想化,那么这里程序将挂起,
                可以通过调整byte数组大小来解决,即确认截取一屏的字节数*/
                if (tmp.startsWith(flagWords) || tmp.indexOf(flagWords) > 0) {
                    return tmp;
                }else if(tmp.indexOf("successfully completed")>0){
                    return tmp;
                }
            }
        } catch (IOException e) {
            tmp = "error";
            e.printStackTrace();
        }

        return tmp;
    }

    /**
     * 读取流中的数据
     *
     * @param end 流中是否含有该标志
     * @return StringBuffer 错误则返回error,否则返回读取的字符串
     */
    public StringBuffer readEndBy(String end) {

        String tmp ;
        StringBuffer buffer = new StringBuffer();
        int read;
        byte[] bytes = new byte[2048];
        end = end==null?"":end;
        try {
            while (0 < (read = remoteInput.read(bytes))) {
                //替换特殊字符
                tmp = new String(bytes,0,read).replaceAll("\\u001B","");
                buffer.append(tmp);
                log.info("#" + tmp + "#");
                //此处仅适用endsWith是为了防止相同结束符存在造成的获取误差
                if (tmp.endsWith(end)) {
                    return buffer;
                }
            }
        } catch (IOException e) {
            buffer = new StringBuffer();
            buffer.append("error");
            e.printStackTrace();
        }

        return buffer;
    }

    /**
     * 关闭连接
     */
    public void close() {
        //关闭流
        if (null != remoteInput) {
            try {
                remoteInput.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (null != remoteOut) {
            remoteOut.close();
        }
        //关闭连接
        try {
            client.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 往流里写入数据
     *
     * @param msg  需要写入流的数据
     */
    public void write(String msg) {
        remoteOut.println(msg);
        remoteOut.flush();
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        TelnetUtil util = new TelnetUtil("10.11.9.*",5023,TerminalType.T_W2KTT);
        util.login("szct****", "sz****");
        StringBuffer tmp = util.execCommand("status socket-usage","[0m");
        System.out.println(tmp.toString());
        util.close();
    }
}

   net中自带的实例工具类,可以参考下

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.special.utils.telnet;

import java.io.IOException;
import org.apache.commons.net.telnet.TelnetClient;

import examples.util.IOUtil;

/***
 * This is an example of a trivial use of the TelnetClient class.
 * It connects to the weather server at the University of Michigan,
 * um-weather.sprl.umich.edu port 3000, and allows the user to interact
 * with the server via standard input.  You could use this example to
 * connect to any telnet server, but it is obviously not general purpose
 * because it reads from standard input a line at a time, making it
 * inconvenient for use with a remote interactive shell.  The TelnetClient
 * class used by itself is mostly intended for automating access to telnet
 * resources rather than interactive use.
 * <p>
 ***/

// This class requires the IOUtil support class!
public final class WeatherTelnet
{

    public final static void main(String[] args)
    {
        TelnetClient telnet;

        telnet = new TelnetClient();

        try
        {
//            telnet.connect("rainmaker.wunderground.com", 3000);
            telnet.connect("10.11.9.5",5023);
        }
        catch (IOException e)
        {
            e.printStackTrace();
            System.exit(1);
        }

        IOUtil.readWrite(telnet.getInputStream(), telnet.getOutputStream(),
                         System.in, System.out);

        try
        {
            telnet.disconnect();
        }
        catch (IOException e)
        {
            e.printStackTrace();
            System.exit(1);
        }

        System.exit(0);
    }

}

猜你喜欢

转载自814318774.iteye.com/blog/2195528