最近有几个需求,对linux,windows服务器和三层交换机进行重启和关机。
Linux:
首先说原理:对linux是通过ssh协议,账号密码登陆后使用命令。直接上代码。使用jsch-0.1.48.jar包
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Properties;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class ControllerLinux {
/**
* 2017-12-25上午10:52:35
* cwy
*
*/
private static ChannelExec channelExec;
private static Session session = null;
private static int timeout = 60000;
// 测试代码
public static void main(String[] args){
try{
versouSshUtil("192.168.10.234","root","38921561",22);
runCmd("init 1","UTF-8");
}catch (Exception e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 连接远程服务器
* @param host ip地址
* @param userName 登录名
* @param password 密码
* @param port 端口
* @throws Exception
*/
public static void versouSshUtil(String host,String userName,String password,int port) throws Exception{
//log.info("尝试连接到....host:" + host + ",username:" + userName + ",password:" + password + ",port:"
//+ port);
JSch jsch = new JSch(); // 创建JSch对象
session = jsch.getSession(userName, host, port); // 根据用户名,主机ip,端口获取一个Session对象
session.setPassword(password); // 设置密码
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config); // 为Session对象设置properties
session.setTimeout(timeout); // 设置timeout时间
session.connect(); // 通过Session建立链接
}
/**
* 在远程服务器上执行命令
* @param cmd 要执行的命令字符串
* @param charset 编码
* @throws Exception
*/
public static void runCmd(String cmd,String charset) throws Exception{
channelExec = (ChannelExec) session.openChannel("exec");
channelExec.setCommand(cmd);
channelExec.setInputStream(null);
channelExec.setErrStream(System.err);
channelExec.connect();
InputStream in = channelExec.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in, Charset.forName(charset)));
String buf = null;
while ((buf = reader.readLine()) != null){
System.out.println(buf);
}
reader.close();
channelExec.disconnect();
}
}
三层交换机:以思科为例。
原理:三层交换机使用java模拟telnet的方式登录,发命令。使用的包commons-net-3.3.jar
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.SocketException;
import org.apache.commons.net.telnet.TelnetClient;
public class TelnetConnection {
/**
* 2017-12-25下午5:45:38
* cwy
*
*/
private TelnetClient telnet = null;
private String prompt = "#$>]";
private String loginPrompt = "login";
private String usernamePrompt = "User Name:";
private String passwordPrompt = "Password:";
private InputStream in;
private PrintStream out;
public TelnetConnection(String host, int port) {
if(telnet == null) {
telnet = new TelnetClient("vt200");
try {
telnet.setDefaultTimeout(5000);
telnet.connect("192.168.10.150",23); //建立一个连接,默认端口是23
this.in = telnet.getInputStream();
this.out = new PrintStream(telnet.getOutputStream());
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException 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).
*/
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 = this.in.read()) != -1) {
sb.append((char)len);
if(pattern.indexOf((char)len) != -1 || sb.toString().endsWith(pattern)) {
return sb.toString();
}
}
} catch (IOException e) {
}
return "";
}
/** * 写操作 * * @param value */
public void write(String value) {
try {
out.println(value);
out.flush();
} catch (Exception e) {
}
}
/** * 向目标发送命令字符串 * * @param command * @return */
public String sendCommand(String command) {
try {
write(command);
return readUntil(prompt + "");
} catch (Exception e) {
}
return "";
}
/** * 关闭连接 */
public void disconnect() {
try {
telnet.disconnect();
} catch (Exception e) {
}
}
/**
* @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) {
}
}
if(this.telnet != null) {
try {
this.telnet.disconnect();
} catch (IOException e) {
}
}
}
public static void main(String[] args) {
try {
System.out.println("启动Telnet...");
String ip = "191.168.10.150";
int port = 23;
String user = "gzyingling";
String password = "gzyingling@2017";
TelnetConnection telnet = new TelnetConnection(ip, port);
telnet.login(user, password, "");
String r1 = telnet.sendCommand("reload");//display snmp-agent local-engineid
String r2 = telnet.sendCommand("Y");
System.out.println(r1);
System.out.println(r2);
telnet.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
对windows的操控使用wmi。java执行写好vbs脚本。当然,参数是通过程序传进脚本的。(远程尚未测试成功,稍后补充)