Java 通过telnet协议 操作远程交换机

/**
 *@date 2015年2月4日 下午3:15:13
 *@author XUQIANG
 *@filename TelnetConnection.java
 *@package com.merit.monitor.device.parameter.sdk
 */
package com.merit.monitor.device.parameter.sdk;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.SocketException;

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

import com.merit.monitor.device.parameter.logs.ILog;
import com.merit.monitor.device.parameter.logs.LogImpl;

/**
 * @author XUQIANG
 *
 */
public class TelnetConnection {

	private static ILog log = new LogImpl();
	
	private TelnetClient telnet = null;
	
//	private String username = "";
	private String password = "";
	private String prompt = "#";
	
	private InputStream in;
	private PrintStream out;
	
	public TelnetConnection(String host, int port) {
		if(telnet == null) {
			telnet = new TelnetClient();
			try {
				telnet.connect(host, port);
				in = telnet.getInputStream();
				out = new PrintStream(telnet.getOutputStream());
			} catch (SocketException e) {
				log.logForException(TelnetConnection.class, e.getMessage());
			} catch (IOException e) {
				log.logForException(TelnetConnection.class, e.getMessage());
			}
		}
	}
	
	/**
	 * @return the prompt
	 */
	public String getPrompt() {
		return prompt;
	}

	/**
	 * @param prompt the prompt to set
	 */
	public void setPrompt(String prompt) {
		this.prompt = prompt;
	}

	/**
	 * 关闭打开的连接
	 * @param telnet
	 */
	public void close(TelnetClient telnet) {
		if(telnet != null) {
			try {
				telnet.disconnect();
			} catch (IOException e) {
				log.logForException(TelnetConnection.class, e.getMessage());
			}
		}
		
		if(this.telnet != null) {
			try {
				this.telnet.disconnect();
			} catch (IOException e) {
				log.logForException(TelnetConnection.class, e.getMessage());
			}
		}
	}
	
	/**
	 * 登录到远程机器中
	 */
	public void login(String username, String password, String prompt) {
		//处理命令行的提示字符
		if(prompt == null || "".equals(prompt)) {
			if(this.prompt.equals("#"))
				prompt = ("root".equals(username)) ? "#" : "$";
		} else {
			this.prompt = prompt;
		}
		this.password = password;
		readUntil("Username:");
		write(username);
		readUntil("Password:");
		write(this.password);
		readUntil(this.prompt + "");
		// 其它交换机登录后如果有提示信息也需要添加
		if(this.prompt.indexOf("Quidway") != -1) 
			readUntil("login");
	}
	
	/** * 读取分析结果 * * @param pattern * @return */
	public String readUntil(String pattern) {
		StringBuffer sb = new StringBuffer();
		
		try {
			int len = 0;
			while((len = in.read()) != -1) {
				sb.append((char)len);
				if(sb.toString().endsWith(pattern)) {
					return sb.toString();
				}
			}
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		return "";
	}
	
	
	/** * 写操作 * * @param value */
	public void write(String value) {
		try {
			out.println(value);
			out.flush();
		} catch (Exception e) {
			log.logForException(TelnetConnection.class, e.getMessage());
		}
	}

	/** * 向目标发送命令字符串 * * @param command * @return */
	public String sendCommand(String command) {
		try {
			write(command);
			return readUntil(prompt + "");
		} catch (Exception e) {
			log.logForException(TelnetConnection.class, e.getMessage());
		}
		return "";
	}

	/** * 关闭连接 */
	public void disconnect() {
		try {
			telnet.disconnect();
		} catch (Exception e) {
			log.logForException(TelnetConnection.class, e.getMessage());
		}
	}
}


Junit

@Test
	public void testTelnet() {

		try {
			System.out.println("启动Telnet...");
			String ip = "191.168.*.*";
			int port = 23;
			String user = "admin";
			String password = "****";
			TelnetConnection telnet = new TelnetConnection(ip, port);
			telnet.setPrompt("<Quidway>");
			telnet.login(user, password, "");
			telnet.setPrompt("[Quidway]");
			String r1 = telnet.sendCommand("system-view");//display snmp-agent local-engineid
			telnet.setPrompt("[Quidway-Ethernet1/0/5]");
			String r2 = telnet.sendCommand("interface Ethernet1/0/5");
			String r3 = telnet.sendCommand("undo shutdown");
			System.out.println("显示结果");
			System.out.println(r1);
			System.out.println(r2);
			System.out.println(r3);
			
			System.out.println((r3.indexOf(telnet.getPrompt()) != -1) && r3.indexOf("^") == -1);
			telnet.disconnect();
		} catch (Exception e) {
			e.printStackTrace();
		}
	
	}

改进后的实现:


 登录到远程机器中

 说明:在登录前,先确认输入用户名的提示符,如果不是Username:,需要设置该值,使用setUsernamePrompt(prompt);

       第二,确认输入密码时的提示符,如果不是Password:,需要设置该值,使用setPasswordPrompt(prompt);

       第三,确认登录后查看是否有登录后的提示信息:如:%Apr 17 04:26:32:256 2000 Quidway SHELL/5/LOGIN:- 1 - admin(191.168.2.227) in unit1 login

                如果末尾不是login,需要指定最后一个单词,使用setLoginPrompt(prompt)。

                如果没有登录提示,设置setLoginPrompt(null);

       第四,执行命令时,如果提示符不是 #、$、>、]中的一个,也需要指定最后一个符号,使用setPrompt(prompt).

 

/**
 *@date 2015年2月4日 下午3:15:13
 *@author XUQIANG
 *@filename TelnetConnection.java
 *@package com.merit.monitor.device.parameter.sdk
 */
package com.meritit.product.eism.telnet.sdk;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.SocketException;

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

import com.meritit.product.eism.telnet.log.ILog;
import com.meritit.product.eism.telnet.log.LogImpl;

/**
 * @author XUQIANG
 *
 */
public class TelnetConnection {

	private static ILog log = new LogImpl();
	
	
	private TelnetClient telnet = null;
	
	private String prompt = "#$>]";
	private String loginPrompt = "login";
	
	private String usernamePrompt = "Username:";
	private String passwordPrompt = "Password:";
	
	
	private InputStream in;
	private PrintStream out;
	
	public TelnetConnection(String host, int port) {
		if(telnet == null) {
			telnet = new TelnetClient();
			try {
				telnet.connect(host, port);
				in = telnet.getInputStream();
				out = new PrintStream(telnet.getOutputStream());
			} catch (SocketException e) {
				log.logForException(TelnetConnection.class, e.getMessage());
			} catch (IOException e) {
				log.logForException(TelnetConnection.class, e.getMessage());
			}
		}
	}
	
	/**
	 * 登录到远程机器中<br>
	 * 说明:在登录前,先确认输入用户名的提示符,如果不是Username:,需要设置该值,使用setUsernamePrompt(prompt);<br>
	 *       第二,确认输入密码时的提示符,如果不是Password:,需要设置该值,使用setPasswordPrompt(prompt);<br>
	 *       第三,确认登录后查看是否有登录后的提示信息:如:%Apr 17 04:26:32:256 2000 Quidway SHELL/5/LOGIN:- 1 - admin(191.168.2.227) in unit1 login <br>
	 *             如果末尾不是login,需要指定最后一个单词,使用setLoginPrompt(prompt)。
	               如果没有登录提示,设置setLoginPrompt(null);
	 *       第四,执行命令时,如果提示符不是 #、$、>、]中的一个,也需要指定最后一个符号,使用setPrompt(prompt).
	 */
	public void login(String username, String password, String prompt) {
		//处理命令行的提示字符
		if(prompt != null && !"".equals(prompt)) {
			this.prompt = prompt;
		} 
		readUntil(this.usernamePrompt);
		write(username);
		readUntil(this.passwordPrompt);
		write(password);
		readUntil(this.prompt);
		if(this.loginPrompt != null)
		        readUntil(this.loginPrompt);
	}
	
	
	/** * 读取分析结果 * * @param pattern * @return */
	public String readUntil(String pattern) {
		StringBuffer sb = new StringBuffer();
		
		try {
			int len = 0;
			while((len = in.read()) != -1) {
				sb.append((char)len);
				if(pattern.indexOf((char)len) != -1 || sb.toString().endsWith(pattern)) {
					return sb.toString();
				}
			}
		} catch (IOException e) {
			log.logForException(TelnetConnection.class, e.getMessage());
		}
		
		return "";
	}
	
	
	/** * 写操作 * * @param value */
	public void write(String value) {
		try {
			out.println(value);
			out.flush();
		} catch (Exception e) {
			log.logForException(TelnetConnection.class, e.getMessage());
		}
	}

	/** * 向目标发送命令字符串 * * @param command * @return */
	public String sendCommand(String command) {
		try {
			write(command);
			return readUntil(prompt + "");
		} catch (Exception e) {
			log.logForException(TelnetConnection.class, e.getMessage());
		}
		return "";
	}

	/** * 关闭连接 */
	public void disconnect() {
		try {
			telnet.disconnect();
		} catch (Exception e) {
			log.logForException(TelnetConnection.class, e.getMessage());
		}
	}

	/**
	 * @return the prompt
	 */
	public String getPrompt() {
		return prompt;
	}

	/**
	 * @param prompt the prompt to set
	 */
	public void setPrompt(String prompt) {
		this.prompt = prompt;
	}

	/**
	 * @return the usernamePrompt
	 */
	public String getUsernamePrompt() {
		return usernamePrompt;
	}

	/**
	 * @param usernamePrompt the usernamePrompt to set
	 */
	public void setUsernamePrompt(String usernamePrompt) {
		this.usernamePrompt = usernamePrompt;
	}

	/**
	 * @return the passwordPrompt
	 */
	public String getPasswordPrompt() {
		return passwordPrompt;
	}

	/**
	 * @param passwordPrompt the passwordPrompt to set
	 */
	public void setPasswordPrompt(String passwordPrompt) {
		this.passwordPrompt = passwordPrompt;
	}

	/**
	 * @return the loginPrompt
	 */
	public String getLoginPrompt() {
		return loginPrompt;
	}

	/**
	 * @param loginPrompt the loginPrompt to set
	 */
	public void setLoginPrompt(String loginPrompt) {
		this.loginPrompt = loginPrompt;
	}

	/**
	 * 关闭打开的连接
	 * @param telnet
	 */
	public void close(TelnetClient telnet) {
		if(telnet != null) {
			try {
				telnet.disconnect();
			} catch (IOException e) {
				log.logForException(TelnetConnection.class, e.getMessage());
			}
		}
		
		if(this.telnet != null) {
			try {
				this.telnet.disconnect();
			} catch (IOException e) {
				log.logForException(TelnetConnection.class, e.getMessage());
			}
		}
	}
	
}

=====================================================================

添加了telnet tab键命令补全功能。

简单记录一下:

单击tab键时,将命令和\t符号一同发送到交换机中,但是不执行命令,所以就不能使用out.println().只能使用out.print().

连续tab键时,需要向服务器发送的命令是,与上次命令不同的地方。就是把上次相同的命令字符要去掉。

例如:

第一次tab时执行: int

发送命令为:  int\t

执行程序为:out.print("int\t");

返回值为:interface

第二次tab时执行: interface e

发送命令为:e\t

执行程序为:out.print("e\t");

返回值为:interface Ethernet

第三次按回车是执行:interface Ethernet 1/0/5

发送命令: 1/0/5       说明:1/0/5前面有个空格

执行程序为:out.println(" 1/0/5");

返回结果为:[Quidway-Ethernet1/0/5]     说明:只有提示符。




源程序如下:

/**
 *@date 2015年3月19日 下午3:15:13
 *@author XUQIANG
 *@filename TelnetConnection.java
 *@package com.merit.monitor.device.parameter.sdk
 */
package com.meritit.product.eism.telnet.sdk;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.SocketException;

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

import com.meritit.product.eism.telnet.log.ILog;
import com.meritit.product.eism.telnet.log.LogImpl;

/**
 * @author XUQIANG
 *
 */
public class TelnetConnection {

	private static ILog log = new LogImpl();
	
	
	private TelnetClient telnet = null;
	
	private String prompt = "#$>]";
	private String loginPrompt = "login";
	
	private String usernamePrompt = "Username:";
	private String passwordPrompt = "Password:";
	
	
	private InputStream in;
	private PrintStream out;
	
	public TelnetConnection(String host, int port) {
		if(telnet == null) {
			telnet = new TelnetClient();
			try {
				telnet.connect(host, port);
				in = telnet.getInputStream();
				out = new PrintStream(telnet.getOutputStream());
			} catch (SocketException e) {
				log.logForException(TelnetConnection.class, e.getMessage());
			} catch (IOException e) {
				log.logForException(TelnetConnection.class, e.getMessage());
			}
		}
	}
	
	/**
	 * 登录到远程机器中<br>
	 * 说明:在登录前,先确认输入用户名的提示符,如果不是Username:,需要设置该值,使用setUsernamePrompt(prompt);<br>
	 *       第二,确认输入密码时的提示符,如果不是Password:,需要设置该值,使用setPasswordPrompt(prompt);<br>
	 *       第三,确认登录后查看是否有登录后的提示信息:如:%Apr 17 04:26:32:256 2000 Quidway SHELL/5/LOGIN:- 1 - admin(191.168.2.227) in unit1 login <br>
	 *             如果末尾不是login,需要指定最后一个单词,使用setLoginPrompt(prompt).
	 *             如果没有登录提示,设置setLoginPrompt(null);
	 *       第四,执行命令时,如果提示符不是 #、$、>、]中的一个,也需要指定最后一个符号,使用setPrompt(prompt).
	 */
	public void login(String username, String password, String prompt) {
		loginForWin(username, password, prompt);
	}
	public String loginForWin(String username, String password, String prompt) {
		//处理命令行的提示字符
		if(prompt != null && !"".equals(prompt)) {
			this.prompt = prompt;
		} 
		String result = "";
		readUntil(this.usernamePrompt);
		write(username);
		readUntil(this.passwordPrompt);
		write(password);
		result = readUntil(this.prompt);
		if(this.loginPrompt != null)
			result += readUntil(this.loginPrompt);
		return result;
	}
	
	
	
	
	/** * 读取分析结果 * * @param pattern * @return */
	private String readUntil(String pattern) {
		StringBuffer sb = new StringBuffer();
		
		try {
			int len = 0;
			while((len = in.read()) != -1) {
				char ch = (char)len;
				sb.append(ch);
				if(pattern.indexOf(ch) != -1 || sb.toString().endsWith(pattern)) {
					return sb.toString();
				}
			}
		} catch (IOException e) {
			log.logForException(TelnetConnection.class, e.getMessage());
		}
		
		return "";
	}
	/**
	 * tab提示  命令补全
	 * @return
	 */
	private String readUntil() {
		StringBuffer sb = new StringBuffer();
		boolean flag = false;
		try {
			int len = 0;
			int i = 0;
			Thread.sleep(500);
			int count = in.available();
//			System.out.println(count);
			while((len = in.read()) != -1) {
				i++;
				char ch = (char)len;
				sb.append(ch);
//				System.out.print(ch);
				if(prompt.indexOf(ch) != -1) {
					flag = true;
				}
				if(flag && i == count) {
					return sb.toString();
				}
			}
		} catch (IOException e) {
			log.logForException(TelnetConnection.class, e.getMessage());
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(sb.toString());
		return sb.toString();
	}
	
	
	/** * 写操作 * * @param value */
	private void write(String value) {
		try {
			out.println(value);
			out.flush();
		} catch (Exception e) {
			log.logForException(TelnetConnection.class, e.getMessage());
		}
	}
	/** * 写操作 * * @param value */
	private void writeTab(String value) {
		try {
//			out.println();
			out.print(value);
			out.flush();
		} catch (Exception e) {
			log.logForException(TelnetConnection.class, e.getMessage());
		}
	}

	/** * 向目标发送命令字符串 * * @param command * @return */
	public String sendCommand(String command) {
		try {
			write(command);
			return readUntil(prompt + "");
		} catch (Exception e) {
			log.logForException(TelnetConnection.class, e.getMessage());
		}
		return "";
	}
	/** * 向目标发送命令字符串 * * @param command * @return */
	public String sendCommand(String command, boolean prom) {
		if(prom && command.indexOf("\t") == -1)
			command += "\t";
		try {
			writeTab(command);
			return readUntil();
		} catch (Exception e) {
			log.logForException(TelnetConnection.class, e.getMessage());
		}
		return "";
	}

	/** * 关闭连接 */
	public void disconnect() {
		try {
			telnet.disconnect();
		} catch (Exception e) {
			log.logForException(TelnetConnection.class, e.getMessage());
		}
	}

	/**
	 * @return the prompt
	 */
	public String getPrompt() {
		return prompt;
	}

	/**
	 * @param prompt the prompt to set
	 */
	public void setPrompt(String prompt) {
		this.prompt = prompt;
	}

	/**
	 * @return the usernamePrompt
	 */
	public String getUsernamePrompt() {
		return usernamePrompt;
	}

	/**
	 * @param usernamePrompt the usernamePrompt to set
	 */
	public void setUsernamePrompt(String usernamePrompt) {
		this.usernamePrompt = usernamePrompt;
	}

	/**
	 * @return the passwordPrompt
	 */
	public String getPasswordPrompt() {
		return passwordPrompt;
	}

	/**
	 * @param passwordPrompt the passwordPrompt to set
	 */
	public void setPasswordPrompt(String passwordPrompt) {
		this.passwordPrompt = passwordPrompt;
	}

	/**
	 * @return the loginPrompt
	 */
	public String getLoginPrompt() {
		return loginPrompt;
	}

	/**
	 * @param loginPrompt the loginPrompt to set
	 */
	public void setLoginPrompt(String loginPrompt) {
		this.loginPrompt = loginPrompt;
	}

	/**
	 * 关闭打开的连接
	 * @param telnet
	 */
	public void close(TelnetClient telnet) {
		if(telnet != null) {
			try {
				telnet.disconnect();
				telnet = null;
			} catch (IOException e) {
				log.logForException(TelnetConnection.class, e.getMessage());
			}
		}
		
		if(this.telnet != null) {
			try {
				this.telnet.disconnect();
				this.telnet = null;
			} catch (IOException e) {
				log.logForException(TelnetConnection.class, e.getMessage());
			}
		}
	}
	
}


转载于:https://my.oschina.net/xuqiang/blog/386549

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值