springboot使用telnet连接设备获取数据

时间:2024-04-13 15:11:41

首先引入依赖,依赖地址:

https://mvnrepository.com/artifact/telnet_client/telnet_client
<dependency>
   <groupId>telnet_client</groupId>
   <artifactId>telnet_client</artifactId>
   <version>0.1.6</version>
</dependency>

本案例使用的是0.1.6版本,如果依赖安装失败,请修改仓库源:

https://clojars.org/repo/

即可安装成功。

程序代码:

import java.io.InputStream;
import java.io.PrintStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.net.telnet.TelnetClient;

public class TelnetUtil {
    public TelnetClient telnet = new TelnetClient();

    public InputStream in;//输入流

    public PrintStream out;//输出流

    public static final String DEFAULT_AIX_PROMPT = ">";//截断标识符
    public static final String PAGE_BREAK_SIGN  = "---- More ----";//分页符


    /**
     * telnet 端口
     */
    public String port;

    /**
     * 用户名
     */
    public String user;

    /**
     * 密码
     */
    public String password;

    /**
     * IP 地址
     */
    public String ip;

    /**
     * 缺省端口
     */
    public static final int DEFAULT_TELNET_PORT = 23;

    public TelnetUtil(String ip, String user, String password) {
        this.ip = ip;
        this.port = String.valueOf(TelnetUtil.DEFAULT_TELNET_PORT);
        this.user = user;
        this.password = password;
    }

    public TelnetUtil(String ip, String port, String user, String password) {
        this.ip = ip;
        this.port = port;
        this.user = user;
        this.password = password;
    }

    /**
     * 连接设备
     * @return boolean 连接成功返回true,否则返回false
     */
    public boolean connect() {

        boolean isConnect = true;

        try {
            telnet.connect(this.ip, Integer.parseInt(this.port));

            this.in = telnet.getInputStream();
            this.out = new PrintStream(telnet.getOutputStream());

            /** Log the user on* */
            this.readUntil("login: ");
            this.write(user);

            this.readUntil("Password: ");
            this.write(password);

            /** Advance to a prompt */
            this.readUntil(DEFAULT_AIX_PROMPT);

        } catch (Exception e) {
            isConnect = false;
            e.printStackTrace();
            return isConnect;
        }
        return isConnect;
    }

    /**
     * 切换root用户方法
     * @param user
     * @param password
     */
    public void su(String user, String password) {
        try {
            write("su" + " - " + user);
            readUntil("Password:");
            write(password);
            readUntil(DEFAULT_AIX_PROMPT);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

/**
 * 处理返回流
 * @param pattern
 * @return
 */
 public String readUntil(String pattern) {
        try {
            char lastChar = pattern.charAt(pattern.length() - 1);//获取截断标识符
            StringBuffer sb = new StringBuffer();
            char ch = (char) in.read();//获取窗口输入

            while (true) {
//                System.out.print("-"+ch);// ---需要注释掉
                sb.append(ch);
                if (ch == lastChar) { //如果含有截断标识进行返回
                    if (sb.toString().endsWith(pattern)) {
                        sb.toString().replace(PAGE_BREAK_SIGN,"");
                        return sb.toString();
                    }
                }
                if(sb.toString().endsWith(PAGE_BREAK_SIGN)){ //设备开启分页检查
                    write((char)32+"");//获取到分页符时,输入空格继续读取数据,(char)32在ASCII中表示空格,
//                    return sb.toString();
                }
                ch = (char) in.read();//获取输入流
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 输入命令窗口,println 方法会在输入命令后自动添加换行符
     * @param value
     */
    public void write(String value) {
        try {
            this.out.println(value);
            this.out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送命令
     * @param command
     * @return
     */
    public String sendCommand(String command) {
        try {
            this.write(command);
            return this.readUntil(DEFAULT_AIX_PROMPT);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     *关闭连接
     */
    public void disconnect() {
        try {
            this.telnet.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送自定义命令,目前只支持:dis int brief,因为调用方法进行过业务处理,不能满足其他命令
     * @param str
     * @return
     */
    public String sendStr(String str) {
        boolean c = this.connect();
        if(!c){
            throw new NumberFormatException("连接不到目标设备");
        }
        String res = this.sendCommand(str);
        this.disconnect();
        return res;
    }
    /**
     * 发送自定义命令,目前只支持:dis ip routing-table protocol static
     * 特殊处理结束符
     * @param str
     * @return
     */
    public String sendIpRouting(String str) {
        boolean c = this.connect();
        if(!c){
            throw new NumberFormatException("连接不到目标设备");
        }
        this.write(str);
        String res = this.readUntilRewrite("Summary count : 0");

        this.disconnect();
        return res;
    }

    /**
     * 重写断言方法,支持自定义断言
     * @param pattern
     * @return
     */
    public String readUntilRewrite(String pattern) {
        try {
            StringBuffer sb = new StringBuffer();
            char ch = (char) in.read();//获取窗口输入

            while (true) {
                sb.append(ch);
                if(sb.toString().endsWith(PAGE_BREAK_SIGN)){ //设备开启分页检查
                    write((char)32+"");//获取到分页符时,输入空格继续读取数据,(char)32在ASCII中表示空格,
                }
                if(sb.toString().endsWith(pattern)){ 
                    sb.toString().replace(PAGE_BREAK_SIGN,"");
                    return sb.toString();
                }
                ch = (char) in.read();//获取输入流
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 结果处理,去掉分页符,制表符,不同系统下的换行符
     * @param str
     * @return
     */
    public String handleStr(String str)
    {
        str = str.replace(PAGE_BREAK_SIGN,"");
        Pattern p = Pattern.compile("\t|\r|\n");
        Matcher m = p.matcher(str);
        return m.replaceAll("");
    }
}

注意:

DEFAULT_AIX_PROMPT 代表的截取结果标识,可以采用自己的标识,或者识别到返回结果结束来取值。
PAGE_BREAK_SIGN 自定义参数,用来识别分页,如果设备开启分页,不进行返回流的分页处理,可能会导致乱码,另一个不进行再次输入,将获取不到完整数据,设备没有开启分页设置,可以不设置此参数。关于分页请看下图:

springboot使用telnet连接设备获取数据

设置分页后:输入回车(enter)代表下一行,输入空格(Space)代表下一页,输入ctrl+c代表结束。

调用:

TelnetUtil telnet = new TelnetUtil(ip, username, password);
String res = telnet.sendStr("dis int brief");
System.out.println(res);

debug控制台输出,后续的处理,根据自己的业务需要,进行对应操作即可。

备注:

public TelnetClient telnet = new TelnetClient();

不设置参数默认使用:VT100版本

可选参数:VT52、VT100、VT200、VT220

设备是windwos系统使用:VT220/VT200