如果大家熟悉Linux的话,一定对ssh,sftp,scp等命令非常熟悉,ssh是一个安全协议,用来在不同系统或者服务器之间进行安全连接,SSH 在连接和传送的过程中会加密所有的数据。
但是SSH一般是基于客户端的或者Linux命令行的,比如客户端的工具:OpenSSH,putty,SSH Tectia;
在linux上大家可以通过ssh username@host连接到所要想连接的主机。
但是如果在J2EE中,如何实现SSH呢?进而可以实现SCP,SFTP的功能呢?下面介绍的JSCH就可以实现下边的功能。
JSCH是一个纯粹的用java实现SSH功能的java  library;

maven依赖
  1. <dependency>
  2. <groupId>com.jcraft</groupId>
  3. <artifactId>jsch</artifactId>
  4. <version>0.1.44</version>
  5. </dependency>

关键类介绍

  • JSch:  作为中心配置点,以及Session的工厂;

This class serves as a central configuration point, and as a factory for Session objects configured with these settings.

  1. Use getSession to start a new Session.
  2. Use one of the addIdentity methods for public-key authentication.
  3. Use setKnownHosts to enable checking of host keys.
  4. See setConfig for a list of configuration options.

  • Session:表示到远程SSH服务器的一个连接,可以包含多个Channels;

A Session represents a connection to a SSH server.One session can contain multiple Channels of various types

A session is opened with connect() and closed with disconnect().

  • Channel :  与Session相关联的通道,有多种不同类型;

The abstract base class for the different types of channel which may be associated with a Session.

  1. shell - ChannelShell :A channel connected to a remote shell (本次使用的Channel)
  2. exec - ChannelExec :A channel connected to a remotely executing program
  3. direct-tcpip - ChannelDirectTCPIP: A Channel which allows forwarding a pair of local streams to/from a TCP-connection to a server on the remote side
  4. sftp - ChannelSftp :A Channel connected to an sftp server (as a subsystem of the ssh server).
  5. subsystem - ChannelSubsystem :A channel connected to a subsystem of the server process

使用步骤

使用Jsch进行SSH连接的具体步骤如下:
  • 步骤1: 使用Jsch获取Session: jsch.getSession()
  • 步骤2: 设置Session的password和属性等: setPassword()/setConfig();
  • 步骤3: 设置SocketFactory(可以不进行设置,使用默认的TCP socket);
  • 步骤4: 打开Session连接:connect();
  • 步骤5: 打开并连接Channel:openChannel()/connect();
  • 步骤6: 获取Channel的inputStream和outputStream,执行指定cmd或其他;
  1. getInputStream():  All data arriving in SSH_MSG_CHANNEL_DATA messages from the remote side can be read from this stream
  2. getOutputStream():  All data written to this stream will be sent in SSH_MSG_CHANNEL_DATA messages to the remote side.
  • 步骤7: 关闭各种资源:输入输出流/Session/Channel等;

创建Session,并打开Session连接

步骤1~步骤4:程序如下

使用SSH协议,连接到Linux,执行指定命令,并获取结果

步骤5~步骤6:程序如下

执行Shell命令,并获取执行结果

测试程序





完整程序

JSCHUtil.java

  1. package com.sssppp.Communication;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.io.OutputStream;
  5. import java.net.InetAddress;
  6. import java.net.InetSocketAddress;
  7. import java.net.Socket;
  8. import java.net.UnknownHostException;
  9. import java.util.Properties;
  10. import com.jcraft.jsch.JSch;
  11. import com.jcraft.jsch.JSchException;
  12. import com.jcraft.jsch.Session;
  13. import com.jcraft.jsch.SocketFactory;
  14. /**
  15. * 相关链接: JSCH api:http://epaul.github.io/jsch-documentation/javadoc/ Example:
  16. * http://www.jcraft.com/jsch/examples/
  17. *
  18. * @author xxxx
  19. *
  20. */
  21. public class JSCHUtil {
  22. private static JSch jsch = new JSch();
  23. /**
  24. * 创建Session,并打开Session连接
  25. *
  26. * @param dstIp
  27. * @param dstPort
  28. * @param localIp
  29. * @param localPort
  30. * @param userName
  31. * @param password
  32. * @param timeOut
  33. * @return
  34. * @throws JSchException
  35. */
  36. public static Session createSession(String dstIp, int dstPort,
  37. final String localIp, final int localPort, String userName,
  38. String password, final int timeOut) throws JSchException {
  39. //jsch.setKnownHosts("/home/foo/.ssh/known_hosts");
  40. // A Session represents a connection to a SSH server
  41. Session session = jsch.getSession(userName, dstIp, dstPort);
  42. session.setPassword(password);
  43. Properties sshConfig = new Properties();
  44. sshConfig.put("StrictHostKeyChecking", "no");//To skip host-key check
  45. session.setConfig(sshConfig);
  46. // this socket factory is used to create a socket to the target host,
  47. // and also create the streams of this socket used by us
  48. session.setSocketFactory(new SocketFactory() {
  49. @Override
  50. public OutputStream getOutputStream(Socket socket)
  51. throws IOException {
  52. return socket.getOutputStream();
  53. }
  54. @Override
  55. public InputStream getInputStream(Socket socket) throws IOException {
  56. return socket.getInputStream();
  57. }
  58. @Override
  59. public Socket createSocket(String host, int port)
  60. throws IOException, UnknownHostException {
  61. Socket socket = new Socket();
  62. if (localIp != null) {
  63. socket.bind(new InetSocketAddress(InetAddress
  64. .getByName(localIp), localPort));
  65. }
  66. socket.connect(
  67. new InetSocketAddress(InetAddress.getByName(host), port),
  68. timeOut);
  69. return socket;
  70. }
  71. });
  72. session.connect(timeOut);
  73. return session;
  74. }
  75. }


SSHCommUtil.java

  1. package com.sssppp.Communication;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.io.OutputStream;
  5. import com.jcraft.jsch.Channel;
  6. import com.jcraft.jsch.JSchException;
  7. import com.jcraft.jsch.Session;
  8. public class SSHCommUtil {
  9. /**
  10. * 测试程序
  11. * @param args
  12. */
  13. public static void main(String[] args) {
  14. String ip = "10.180.137.241";
  15. int port = 22;
  16. String localIp = null;
  17. int localPort = 0;
  18. int timeOut = 3000;
  19. String userName = "xxx";
  20. String password = "xxx";
  21. String[] cmds = new String[] { "ifconfig | grep eth0\n",
  22. "cat /etc/redhat-release\n" };
  23. String[] result = null;
  24. try {
  25. result = execShellCmdBySSH(ip, port, localIp, localPort, timeOut,
  26. userName, password, cmds);
  27. } catch (Exception e) {
  28. e.printStackTrace();
  29. }
  30. if (result != null) {
  31. for (String string : result) {
  32. System.out.println(string);
  33. System.out.println("-------------------");
  34. }
  35. }
  36. }
  37. /**
  38. * 使用SSH协议,连接到Linux Shell,执行脚本命令,并获取结果
  39. *
  40. * @param dstIp
  41. * @param dstport
  42. * default :22
  43. * @param localIp
  44. * @param localPort
  45. * @param timeOut
  46. * @param userName
  47. * @param password
  48. * @param cmds
  49. * @return
  50. * @throws Exception
  51. */
  52. public static String[] execShellCmdBySSH(String dstIp, int dstport,
  53. String localIp, int localPort, int timeOut, String userName,
  54. String password, String... cmds) throws Exception {
  55. Session session = null;
  56. Channel channel = null;
  57. InputStream is = null;
  58. OutputStream os = null;
  59. try {
  60. session = JSCHUtil.createSession(dstIp, dstport, localIp,
  61. localPort, userName, password, timeOut);
  62. channel = session.openChannel("shell");
  63. // Enable agent-forwarding.
  64. // ((ChannelShell)channel).setAgentForwarding(true);
  65. // Choose the pty-type "vt102".
  66. // ((ChannelShell)channel).setPtyType("vt102");
  67. // Set environment variable "LANG" as "ja_JP.eucJP".
  68. // ((ChannelShell)channel).setEnv("LANG", "ja_JP.eucJP");
  69. channel.connect();
  70. is = channel.getInputStream();
  71. os = channel.getOutputStream();
  72. String[] result = new String[cmds.length];
  73. for (int i = 0; i < cmds.length; i++) {
  74. result[i] = sendCommand(is, os, cmds[i]);
  75. }
  76. return result;
  77. } catch (JSchException e) {
  78. if (e.getMessage().contains("Auth fail")) {
  79. throw new Exception("Auth error");
  80. } else {
  81. throw new Exception("Connect error");
  82. }
  83. } catch (Exception e) {
  84. throw e;
  85. } finally {
  86. try {
  87. is.close();
  88. } catch (IOException e) {
  89. }
  90. try {
  91. os.close();
  92. } catch (IOException e) {
  93. }
  94. channel.disconnect();
  95. session.disconnect();
  96. }
  97. }
  98. /**
  99. * 执行Shell命令,并获取执行结果
  100. *
  101. * @param is
  102. * @param os
  103. * @param cmd
  104. * @return
  105. * @throws IOException
  106. */
  107. private static String sendCommand(InputStream is, OutputStream os,
  108. String cmd) throws IOException {
  109. os.write(cmd.getBytes());
  110. os.flush();
  111. StringBuffer sb = new StringBuffer();
  112. int beat = 0;
  113. while (true) {
  114. if (beat > 3) {
  115. break;
  116. }
  117. if (is.available() > 0) {
  118. byte[] b = new byte[is.available()];
  119. is.read(b);
  120. sb.append(new String(b));
  121. beat = 0;
  122. } else {
  123. if (sb.length() > 0) {
  124. beat++;
  125. }
  126. try {
  127. Thread.sleep(sb.toString().trim().length() == 0 ? 1000
  128. : 300);
  129. } catch (InterruptedException e) {
  130. }
  131. }
  132. }
  133. return sb.toString();
  134. }
  135. }




【Jsch】使用SSH协议连接到远程Shell执行脚本的更多相关文章

  1. 【Telnet】使用Telnet协议连接到远程Shell执行脚本

    介绍 本文介绍如何通过Telnet协议连接到远程Shell,执行脚本,并获取执行结果: 相关文章: <[Jsch]使用SSH协议连接到远程Shell执行脚本>http://www.cnbl ...

  2. TortoiseSVN使用svn+ssh协议连接服务器时重复提示输入密码

    当使用svn+ssh协议连接svn服务器时,ssh会提示请求认证,由于不是svn客户端程序来完成ssh的认证,所以不会缓存密码. 而svn客户端通常会建立多个版本库的连接,当密码没有缓存的时候,就会重 ...

  3. linux-ssh远程后台执行脚本-放置后台执行问题(转)

    写了一个监控负载的小脚本(死循环,测试结束后再kill对应进程),因需要监控多台服务器,所以在一台服务器上使用ssh统一执行脚本遇到问题:使用ssh root@172.16.146.20 '/usr/ ...

  4. Findout之为什么公司内部不能使用SSH协议连接外网服务器

    今天在公司学习Linux的过程中,想试着像在Windows中操作Github一样对代码进行克隆,只不过是使用命令行的方式.根据一篇博文(Linux下初次使用Github配置)进行了配置,当我进行到第二 ...

  5. 一步一步学Python(2) 连接多台主机执行脚本

    最近在客户现场,每日都需要巡检大量主机系统的备库信息.如果一台台执行,时间浪费的就太冤枉了. 参考同事之前写的一个python脚本,配合各主机上写好的shell检查脚本,实现一次操作得到所有巡检结果. ...

  6. linux集群自动化搭建(生成密钥对+分发公钥+远程批量执行脚本)

    之前介绍过ansible的使用,通过ssh授权批量控制服务器集群 但是生成密钥和分发公钥的时候都是需要确认密码的,这一步也是可以自动化的,利用ssh + expect + scp就可以实现,其实只用这 ...

  7. shell脚本学习—Shell执行脚本

    Shell作用是解释执行用户的命令,用户输入一条命令,Shell就解释执行这一条,这种方式称为交互式,但还有另一种执行命令的方式称为批处理方式,用户事先写一个Shell脚本,Shell可以一次把这些命 ...

  8. Shell执行脚本

    Shell作用是解释执行用户的命令,用户输入一条命令,Shell就解释执行这一条,这种方式称为交互式,但还有另一种执行命令的方式称为批处理方式,用户事先写一个Shell脚本,Shell可以一次把这些命 ...

  9. 在mac下使用终端命令通过ssh协议连接远程linux系统,代替windows的putty

    指令:ssh username@server.address.com 事例:wangmingdeMacBook-Pro:~ xxxxxxxxxx$ ssh root@XXXX.net The auth ...

随机推荐

  1. 分析一个delphi程序

    系统 : Windows xp 程序 : k4n6 程序下载地址 :https://pan.baidu.com/s/1pLANxyj 要求 : 注册机编写 使用工具 : OD & DeDe 可 ...

  2. 自定义AlertDialog的样式

    一.在XML中定义好要显示的AlertDialog的布局 二.在代码中创建alertdialog 对象 AlertDialog dialog = new AlertDialog.Builder(thi ...

  3. C++学习笔记27:异常处理机制

    一.异常处理机制基础 异常的定义 程序中可以检测的运行不正常的情况 异常处理的基本流程 某段程序代码在执行操作时发生特殊情况,引发一个特定的异常 另一段程序代码捕获该异常并处理它 二.异常的引发 th ...

  4. tinyhttpd源码分析

    我们经常使用网页,作为开发人员我们也部署过httpd服务器,比如开源的apache,也开发过httpd后台服务,比如fastcgi程序,不过对于httpd服务器内部的运行机制,却不是非常了解,前几天看 ...

  5. 安装在CloudStack时CentOS6.4中安装MySQL通过mysql_secure_installation方式修改密码

    在安装CloudStack时,通过mysql_secure_installation方式修改密码 01 [root@test ~]# /usr/bin/mysql_secure_installatio ...

  6. IC卡复位应答ATR的数据元和它们的意义

    ISO/IEC 7816-3标准中对ATR的数据串和数据元做了规定和描述.ATR的数据元和它们的意义: 数据元 说明 TS 起始字符 T0 格式字符 TA1,TB1,TC1,TD1,... 接口字符 ...

  7. yii accessRules用法

    访问控制过滤器(Access Control Filter)访问控制过滤器是检查当前用户是否能执行访问的controller action的初步授权模式. 这种授权模式基于用户名,客户IP地址和访问类 ...

  8. Swiper 中文API手册(share)

    本文分享自 http://www.cnblogs.com/scavengers/p/3760449.html ---------------------------华丽的分割线------------ ...

  9. Swift解算法——台阶问题

    题目:一个台阶总共有n级,如果一次可以跳1级,也可以跳2级. 求总共有多少总跳法,并分析算法的时间复杂度.   首先对题目进行分析: 台阶一共有n级 因此当n = 1时——只有一种跳法       当 ...

  10. JavaScript设计模式:读书笔记(未完)

    该篇随我读书的进度持续更新阅读书目:<JavaScript设计模式> 2016/3/30 2016/3/31 2016/4/8 2016/3/30: 模式是一种可复用的解决方案,可用于解决 ...