packagecom.sunsheen.blockchain.admin.utils;importjava.io.BufferedReader;importjava.io.File;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.io.OutputStream;importjava.io.PrintWriter;importjava.util.Properties;importorg.apache.http.util.Asserts;importch.ethz.ssh2.ChannelCondition;importch.ethz.ssh2.Connection;importch.ethz.ssh2.StreamGobbler;importcom.jcraft.jsch.Channel;importcom.jcraft.jsch.ChannelSftp;importcom.jcraft.jsch.ChannelShell;importcom.jcraft.jsch.JSch;importcom.jcraft.jsch.JSchException;importcom.jcraft.jsch.Session;importcom.sunsheen.blockchain.admin.common.ServersConstant;public classSSHUtil {/*** 连接服务器
*@paramhost
*@paramuser
*@parampwd
*@return*@throwsJSchException*/
public static synchronized Session connect(String host,String user,String pwd) throwsJSchException {
JSch jsch= newJSch();
Session session= jsch.getSession(user, host, 22);
session.setConfig("StrictHostKeyChecking", "no");//java.util.Properties config = new java.util.Properties();//config.put("StrictHostKeyChecking", "no");
session.setPassword(pwd);
session.connect();returnsession;
}/*** 执行命令集
*@paramsession
*@paramcmds
*@return*@throwsIOException
*@throwsJSchException*/
public staticString execCommandByShell(Session session,String[] cmds)throwsIOException, JSchException {
String result= "";//2.尝试解决 远程ssh只能执行一句命令的情况
ChannelShell channelShell = (ChannelShell) session.openChannel("shell");
InputStream inputStream= channelShell.getInputStream();//从远端到达的数据都能从这个流读取到
channelShell.setPty(true);
channelShell.connect();
OutputStream outputStream= channelShell.getOutputStream();//写入该流的数据//都将发送到远程端//使用PrintWriter 就是为了使用println 这个方法//好处就是不需要每次手动给字符加\n
PrintWriter printWriter = newPrintWriter(outputStream);for(String cmd:cmds) {
printWriter.println(cmd);
}
printWriter.println("exit");//为了结束本次交互
printWriter.flush();//把缓冲区的数据强行输出
returnresult;
}/*** 单个文件上传
*@paramfile 上传的文件
*@paramremoteFolder 服务器上存放当前文件的文件夹
*@paramuploadFileName 上传文件的名字*/
public static void postFile(InputStream fileStream,String remoteFolder,String uploadFileName) throwsException{//上传文件的个数应该跟对应文件夹相同
if((null==fileStream || null==remoteFolder))return;
String username=ServersConstant.USERNAME;
String password=ServersConstant.PASSWORD;
String address=ServersConstant.ADDRES;int port =ServersConstant.PORT;
ChannelSftp sftp= null;
Channel channel= null;
Session sshSession= null;try{//创建连接
JSch jsch = newJSch();
sshSession=jsch.getSession(username, address, port);
sshSession.setPassword(password);//获取session
Properties sshConfig = newProperties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();//得到sftp
channel = sshSession.openChannel("sftp");
channel.connect();
sftp=(ChannelSftp) channel;
sftp.cd(remoteFolder);//进入对应存放日志文件的目录
sftp.put(fileStream, uploadFileName);//写入文件
}finally{//关闭sftp信道
if (sftp != null) {if(sftp.isConnected()) {
sftp.disconnect();
}
}//关闭channel管道
if (channel != null) {if(channel.isConnected()) {
channel.disconnect();
}
}//关闭session
if (sshSession != null) {if(sshSession.isConnected()) {
sshSession.disconnect();
}
}
}
}/*** 转换指令到服务器执行
*@paramcommand 要执行的指令*/
public static voidtransferCommand(String... commands){
String romoteAddr=ServersConstant.ADDRES;
String username=ServersConstant.USERNAME;
String password=ServersConstant.PASSWORD;try{
Connection connection= new Connection(romoteAddr);//创建一个连接实例
connection.connect();//Now connect
boolean isAuthenticated = connection.authenticateWithPassword(username, password);//認證
Asserts.check(isAuthenticated, "用戶名或密碼錯誤!");
ch.ethz.ssh2.Session sess= connection.openSession();//創建一個會話
sess.requestPTY("bash");
sess.startShell();
InputStream stdout= newStreamGobbler(sess.getStdout());
InputStream stderr= newStreamGobbler(sess.getStderr());
BufferedReader stdoutReader= new BufferedReader(newInputStreamReader(stdout));
BufferedReader stderrReader= new BufferedReader(newInputStreamReader(stderr));//向服务器上输入命令
PrintWriter out = newPrintWriter(sess.getStdin());for(String command : commands){
out.println(command);
}
out.close();
sess.waitForCondition(ChannelCondition.CLOSED|ChannelCondition.EOF | ChannelCondition.EXIT_STATUS,100);//关闭连接
sess.close();
connection.close();
stderrReader.close();
stdoutReader.close();
}catch(IOException e) {
e.printStackTrace();
}
}/*** 下载指定文件到本地指定文件夹oo
*@paramserversFolder 服务器文件所在目录 /opt/log
*@paramfileName 需要下载的文件名 monitor.log
*@paramlocalFolder 本地存放文件的文件夹 d:\\logs*/
public static voiddownload(String serversFolder,String fileName,String localFolder) {
String username=ServersConstant.USERNAME;
String password=ServersConstant.PASSWORD;
String address=ServersConstant.ADDRES;int port =ServersConstant.PORT;
ChannelSftp sftp= null;
Channel channel= null;
Session sshSession= null;try{//创建连接
JSch jsch = newJSch();
sshSession=jsch.getSession(username, address, port);
sshSession.setPassword(password);//获取session
Properties sshConfig = newProperties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();//得到sftp
channel = sshSession.openChannel("sftp");
channel.connect();
sftp=(ChannelSftp) channel;//进入服务器文件夹
sftp.cd(serversFolder);//创建本地文件夹
File downloadFile = newFile(localFolder);if(!downloadFile.exists())
downloadFile.mkdirs();//下载
String serversFile = serversFolder +"/"+fileName;
sftp.get(serversFile,localFolder);
System.out.println(fileName+"已下载到:"+localFolder);
}catch(Exception e) {
e.printStackTrace();
}finally{//关闭sftp信道
if (sftp != null) {if(sftp.isConnected()) {
sftp.disconnect();
}
}//关闭channel管道
if (channel != null) {if(channel.isConnected()) {
channel.disconnect();
}
}//关闭session
if (sshSession != null) {if(sshSession.isConnected()) {
sshSession.disconnect();
}
}
}
}
}