首页 > Web开发 > 详细

【Jsch】使用SSH协议连接到远程Shell执行脚本

时间:2017-01-03 15:16:58      阅读:1062      评论:0      收藏:0      [点我收藏+]
技术分享
如果大家熟悉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.Jsch;
  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 apihttp://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. * @param dstIp
  26. * @param dstPort
  27. * @param localIp
  28. * @param localPort
  29. * @param userName
  30. * @param password
  31. * @param timeOut
  32. * @return
  33. * @throws JSchException
  34. */
  35. public static Session createSession(String dstIp, int dstPort,
  36. final String localIp, final int localPort, String userName,
  37. String password, final int timeOut) throws JSchException {
  38. // A Session represents a connection to a SSH server
  39. Session session = jsch.getSession(userName, dstIp, dstPort);
  40. session.setPassword(password);
  41. Properties sshConfig = new Properties();
  42. sshConfig.put("StrictHostKeyChecking", "no");
  43. session.setConfig(sshConfig);
  44. // this socket factory is used to create a socket to the target host,
  45. // and also create the streams of this socket used by us
  46. session.setSocketFactory(new SocketFactory() {
  47. @Override
  48. public OutputStream getOutputStream(Socket socket)
  49. throws IOException {
  50. return socket.getOutputStream();
  51. }
  52. @Override
  53. public InputStream getInputStream(Socket socket) throws IOException {
  54. return socket.getInputStream();
  55. }
  56. @Override
  57. public Socket createSocket(String host, int port)
  58. throws IOException, UnknownHostException {
  59. Socket socket = new Socket();
  60. if (localIp != null) {
  61. socket.bind(new InetSocketAddress(InetAddress
  62. .getByName(localIp), localPort));
  63. }
  64. socket.connect(
  65. new InetSocketAddress(InetAddress.getByName(host), port),
  66. timeOut);
  67. return socket;
  68. }
  69. });
  70. session.connect(timeOut);
  71. return session;
  72. }
  73. }

SSHCommUtil.java

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









































【Jsch】使用SSH协议连接到远程Shell执行脚本

原文:http://www.cnblogs.com/ssslinppp/p/6244653.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!