如果大家熟悉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. iOS 渐变进度条

    #import <UIKit/UIKit.h> @interface JianBianView : UIView //为了增加一个表示进度条的进行,可们可以使用mask属性来屏蔽一部分 @ ...

  2. MAC按键以及快捷键

    使用普通的非Mac自带的键盘的同志们,想要在Mini Mac上面想要使用键盘,则推荐使用Mac系统自带的虚拟键盘,这样就可以查看普通键盘上每个键对应的Mac系统上是什么. 查看Mac系统上的虚拟键盘的 ...

  3. 救援linux

    挂载分区 mount /dev/sdaX /mnt/ 挂载其他 mount --bind /dev/ /mnt/dev/ mount --bind /proc/ /mnt/proc/ mount -- ...

  4. Web Form 和asp.net mvc 差别

    Asp.net MVC 和web Form的基本区别 Web Form ASP.NET MVC 视图和逻辑紧密耦合 视图和逻辑分离 页面(给予文件的URL) 控制器(基于路由的URL) 状态管理(视图 ...

  5. sql developer 要求输入jdk地址

    困扰了好久  终于找到解决办法了. 将sql developer改为 兼容模式和管理员方式运行,选择java.exe的路径 终于可以在64位系统下顺利使用了.

  6. jQuery中bind方法和live方法区别解析

    Javascript中的事件有它的独特性,有默认的执行事件,例如冒泡就是其中的一个.在很多比较复杂的应用程序中,停止事件的冒泡或捕获在程序开发当中是十分有用的,而在IE中有它的独特方式来阻止事件的冒泡 ...

  7. DirectShow开发快速入门之慨述

    摘要:本篇文档概括性的介绍了DirectShow的主要组成部分,以及一些Directshow的基本概念.熟悉这些基本的知识对于Directshow的应用开发或者过滤器的开发者都会有所帮助. Direc ...

  8. PPT设计宝典!十招教你做出拿得出手的PPT

    据说上班用 excel 的比 word 的工资高,用 ppt 的比用 excel 的工资高.无论如何,在职场演讲汇报中,PPT 扮演着至关重要的角色. 在本文我们将用 10 个超级技巧来解决糟糕的演示 ...

  9. ArcGIS for Android_离在线一体化核心技术基本流程

    核心思想: a.数据首先存储于ArcSDE中,要素添加GlobleID,图层数据启用数据归档或开启版本化.b.然后将ArcSDE数据库托管于ArcGIS for Server作为数据存储.c.在Arc ...

  10. Winform绑定数据源的几种方式?

    第一种:DataSet ds=new DataSet (); this.dataGridView1.DataSource=ds.Table[0]; 第二种:DataTable dt=new DataT ...