java程序使用Jsch 实现 ssh连接

2024-02-09 17:38

本文主要是介绍java程序使用Jsch 实现 ssh连接,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这里写目录标题

  • Jsch
    • 一、简介
    • 二、Jsch的使用
      • 1、连接到服务器
      • 2、执行命令
        • ChannelShell和ChannelExec区别?
      • 3、利用JSch实现SFTP下载、上传文件
    • 三、Jsch的封装,sshxcute
  • 四、Hutool工具类
    • 使用
      • 使用
        • ssh连接到远程主机
        • 端口映射
        • 其它方法

Jsch

一、简介

JSch是SSH2的纯Java实现 。

JSch允许您连接到sshd服务器并使用端口转发,X11转发,文件传输等,并且您可以将其功能集成到您自己的Java程序中。JSch已获得BSD样式许可。

为什么用选择 Jsch?

最初,我们开发此产品的动机是让我们纯Java X服务器 WiredX的用户享受安全的X会话。因此,我们的工作主要针对实现X11转发的SSH2协议。但是,当然,我们现在也对添加其他功能(例如端口转发,文件传输,终端仿真等)感兴趣。

SSH2

不用说,SSH支持安全的远程登录,安全的文件传输以及安全的TCP / IP和X11转发。它可以自动加密,认证和压缩传输的数据。SSH协议有两个不兼容的版本:SSH1和SSH2。发明SSH2的目的是避免有关RSA的专利问题(RSA专利已过期),并解决SSH1所存在的某些数据完整性问题,还有其他一些技术原因。SSH2协议已在IETF Secure Shell工作组上进行了标准化, 有关SSH2协议的草案可从Web上获得。在开发JSch时,我们现在参考以下文档:

  • SSH协议架构
  • SSH传输层协议
  • Diffie-Hellman组交换SSH传输层协议
  • SSH连接协议
  • SSH认证协议

使用JSch的应用程序

  • Ant(1.6或更高版本).
    JSch已用于Ant的sshexec和scp任务。
  • Eclipse(3.0).
    我们的Eclipse-CVSSSH2插件已包含在Eclipse SDK 3.0中。该插件将允许您通过JSch获得ssh2对远程CVS存储库的访问。
  • NetBeans 5.0(及更高版本)
  • Jakarta Commons VFS
  • Maven Wagon
  • 适用于WebSphere软件的Rational Application Devloper
  • HP Storage Essentials
  • JIRA
  • Trac WikiOutputStreamPlugin

二、Jsch的使用

API:http://epaul.github.io/jsch-documentation/javadoc/com/jcraft/jsch/JSch.html

1、连接到服务器

public class JSchDemo {private String ipAddress;   //主机ipprivate String username;   // 账号private String password;   // 密码private int port;  // 端口号Session session;public JSchDemo(String ipAddress, String username, String password, int port) {this.ipAddress = ipAddress;this.username = username;this.password = password;this.port = port;}/***  连接到指定的ip*/public void connect() {try {JSch jsch = new JSch();if (port < 0 || port > 65535){//连接服务器,如果端口号错误,采用默认端口session = jsch.getSession(username, ipAddress);}else {session = jsch.getSession(username, ipAddress, port);}//设置登录主机的密码session.setPassword(password);//如果服务器连接不上,则抛出异常if (session == null) {throw new Exception("session is null");}//设置首次登录跳过主机检查session.setConfig("StrictHostKeyChecking", "no");//设置登录超时时间session.connect(3000);} catch (Exception e) {log.error(e.getMessage(),e);}}
}

在这里插入图片描述

一个 Session 表示一个与SSH服务器的连接。一个 Session 可以包含多种多样的 Channel ,并且创建openChannel(java.lang.String)

一个 session 被一个 connect() 打开和被一个 disconnect() 关闭。

事实上一个 Session 实现 Runnable 接口 是一个实现细节。

关于Session的使用,创建连接后这个session是一直可用的,所以不需要关闭。由Session中open的Channel在使用后应该关闭。


2、执行命令

/*** 执行相关的命令(交互式)* @param command* @return*/
public int execute(String command) {int returnCode = 0;ChannelShell channel = null;PrintWriter printWriter = null;BufferedReader input = null;stdout = new Vector<String>();try {//建立交互式通道channel = (ChannelShell) session.openChannel("shell");channel.connect();//获取输入InputStreamReader inputStreamReader = new InputStreamReader(channel.getInputStream());input = new BufferedReader(inputStreamReader);//输出printWriter = new PrintWriter(channel.getOutputStream());printWriter.println(command);printWriter.println("exit");printWriter.flush();log.info("The remote command is: ");String line;while ((line = input.readLine()) != null) {stdout.add(line);System.out.println(line);}} catch (Exception e) {log.error(e.getMessage(),e);return -1;}finally {IoUtil.close(printWriter);IoUtil.close(input);if (channel != null) {//关闭通道channel.disconnect();}}return returnCode;
}public void close(){if (session != null) {session.disconnect();}
}

在这里插入图片描述在这里插入图片描述

ChannelShell和ChannelExec区别?

参考:https://blog.csdn.net/u013066244/article/details/70911585

ChannelShell

对于ChannelShell,以输入流的形式,提供命令和输入这些命令,这就像在本地计算机上使用交互式shell(它通常用于:交互式使用)

ChannelExec

对于ChannelExec,在调用connect()方法之前这个命令提供了setCommand()方法,并且这些命令作为输入将以输入流的形式被发送出去。(通常,你只能有调用setCommand()方法一次,多次调用只有最后一次生效),但是你可以使用普通shell的分隔符(&,&&,|,||,; , \n, 复合命令)来提供多个命令。这就像在你本机上执行一个shell脚本一样(当然,如果一个命令本身就是个交互式shell,这样就像ChannelShell)

明显:使用命令通道更容易,因为您不需要处理命令提示符。

/*** 执行相关的命令(输入式)* @param command* @return*/public int execute(String command) {int returnCode = 0;ChannelExec channel = null;PrintWriter printWriter = null;BufferedReader input = null;try {channel = (ChannelExec) session.openChannel("exec");channel.setCommand(command);InputStream in = channel.getInputStream();channel.connect();BufferedReader inputReader = new BufferedReader(new InputStreamReader(in, "GBK"));String inputLine;while ((inputLine = inputReader.readLine()) != null) {System.out.println(inputLine);}channel.disconnect();session.disconnect();} catch (Exception e) {log.error(e.getMessage(), e);return -1;} finally {IoUtil.close(printWriter);IoUtil.close(input);if (channel != null) {//关闭通道channel.disconnect();}if (session != null) {session.disconnect();}}return returnCode;}

3、利用JSch实现SFTP下载、上传文件

/***	从SFTP服务器下载文件 
*/
private static void sftp_put(Session session, String uploadFileName) throws Exception {  Channel channel = null;  try {  //创建sftp通信通道  channel = (Channel) session.openChannel("sftp");  channel.connect(1000);  ChannelSftp sftp = (ChannelSftp) channel;  //进入服务器指定的文件夹  sftp.cd("/root");  //列出服务器指定的文件列表  Vector v = sftp.ls("/");  for(int i=0;i<v.size();i++){  System.out.println(v.get(i));  }  //以下代码实现从本地上传一个文件到服务器,如果要实现下载,对换以下流就可以了  OutputStream outstream = sftp.put(uploadFileName);  InputStream instream = new FileInputStream(new File("C:\\aa.txt"));  byte b[] = new byte[1024];  int n;  while ((n = instream.read(b)) != -1) {  outstream.write(b, 0, n);  }  outstream.flush();  outstream.close();  instream.close();  } catch (Exception e) {  e.printStackTrace();  } finally {  session.disconnect();  channel.disconnect();  }  
}  /* * 从SFTP服务器下载文件 * @param ftpHost SFTP IP地址 * @param ftpUserName SFTP 用户名 * @param ftpPassword SFTP用户名密码 * @param ftpPort SFTP端口 * @param ftpPath SFTP服务器中文件所在路径 格式: ftptest/aa * @param localPath 下载到本地的位置 格式:H:/download * @param fileName 文件名称 */  
public static void downloadSftpFile(String ftpHost, String ftpUserName,  String ftpPassword, int ftpPort, String ftpPath, String localPath,  String fileName) throws JSchException {  Session session = null;  Channel channel = null;  JSch jsch = new JSch();  session = jsch.getSession(ftpUserName, ftpHost, ftpPort);  session.setPassword(ftpPassword);  session.setTimeout(100000);  Properties config = new Properties();  config.put("StrictHostKeyChecking", "no");  session.setConfig(config);  session.connect();  channel = session.openChannel("sftp");  channel.connect();  ChannelSftp chSftp = (ChannelSftp) channel;  String ftpFilePath = ftpPath + "/" + fileName;  String localFilePath = localPath + File.separatorChar + fileName;  try {  chSftp.get(ftpFilePath, localFilePath);  } catch (Exception e) {  e.printStackTrace();  } finally {  chSftp.quit();  channel.disconnect();  session.disconnect();  }  }  
}

参考链接:https://blog.csdn.net/u013467442/article/details/69642148


三、Jsch的封装,sshxcute

面向 Java 开发与测试人员的远程执行 Linux/UNIX 系统上任务的框架 — sshxcute

JSch 是 SSH2 的一个纯 Java 实现。它可以连接到一个 sshd 服务器,使用端口转发,X11 转发,文件传输等等。但是这个类库毕竟偏向底层,上手与实际运行起来不太方便,sshxcute 框架正是基于 JSch 封装的,提供了更为便捷的 API 借口,更加灵活实用的功能,从而可以让开发与测试人员更加得心应手的使用。sshxcute 是一个框架,它允许工程师利用 Java 代码通过 SSH 连接远程执行 Linux/UNIX 系统上的命令或者脚本,这种方式不管是针对软件测试还是系统部署,都简化了自动化测试与系统环境部署的步骤。

框架源码:https://gitee.com/charkeyqk/sshxcute

最后一次更新在 2014-03-01

使用:https://www.ibm.com/developerworks/cn/opensource/os-sshxcute/#ibm-pcon


四、Hutool工具类

发现 hutool 对Jsch做了封装,使用起来更加简单方便,不需要自己再去实现了。

https://hutool.cn/docs/#/extra/Jsch%E5%B0%81%E8%A3%85/Jsch%E5%B7%A5%E5%85%B7-JschUtil

使用

引入jsch

<dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.54</version>
</dependency>

说明 截止本文档撰写完毕,jsch的最新版为0.1.54,理论上应引入的版本应大于或等于此版本。

使用

ssh连接到远程主机
//新建会话,此会话用于ssh连接到跳板机(堡垒机),此处为10.1.1.1:22
Session session = JschUtil.getSession("10.1.1.1", 22, "test", "123456");
端口映射
//新建会话,此会话用于ssh连接到跳板机(堡垒机),此处为10.1.1.1:22
Session session = JschUtil.getSession("10.1.1.1", 22, "test", "123456");// 将堡垒机保护的内网8080端口映射到localhost,我们就可以通过访问http://localhost:8080/访问内网服务了
JschUtil.bindPort(session, "172.20.12.123", 8080, 8080);
其它方法
  • generateLocalPort 生成一个本地端口(从10001开始尝试,找到一个未被使用的本地端口)
  • unBindPort 解绑端口映射
  • openAndBindPortToLocal 快捷方法,将连接到跳板机和绑定远程主机端口到本地使用一个方法搞定
  • close 关闭SSH会话

这篇关于java程序使用Jsch 实现 ssh连接的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/694884

相关文章

Java图片压缩三种高效压缩方案详细解析

《Java图片压缩三种高效压缩方案详细解析》图片压缩通常涉及减少图片的尺寸缩放、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等,:本文主要介绍Java图片压缩三种高效... 目录一、基于OpenCV的智能尺寸压缩技术亮点:适用场景:二、JPEG质量参数压缩关键技术:压缩效果对比

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

Redis分片集群的实现

《Redis分片集群的实现》Redis分片集群是一种将Redis数据库分散到多个节点上的方式,以提供更高的性能和可伸缩性,本文主要介绍了Redis分片集群的实现,具有一定的参考价值,感兴趣的可以了解一... 目录1. Redis Cluster的核心概念哈希槽(Hash Slots)主从复制与故障转移2.

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

使用Python实现一键隐藏屏幕并锁定输入

《使用Python实现一键隐藏屏幕并锁定输入》本文主要介绍了使用Python编写一个一键隐藏屏幕并锁定输入的黑科技程序,能够在指定热键触发后立即遮挡屏幕,并禁止一切键盘鼠标输入,这样就再也不用担心自己... 目录1. 概述2. 功能亮点3.代码实现4.使用方法5. 展示效果6. 代码优化与拓展7. 总结1.

Mybatis 传参与排序模糊查询功能实现

《Mybatis传参与排序模糊查询功能实现》:本文主要介绍Mybatis传参与排序模糊查询功能实现,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、#{ }和${ }传参的区别二、排序三、like查询四、数据库连接池五、mysql 开发企业规范一、#{ }和${ }传参的

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Docker镜像修改hosts及dockerfile修改hosts文件的实现方式

《Docker镜像修改hosts及dockerfile修改hosts文件的实现方式》:本文主要介绍Docker镜像修改hosts及dockerfile修改hosts文件的实现方式,具有很好的参考价... 目录docker镜像修改hosts及dockerfile修改hosts文件准备 dockerfile 文

Java利用docx4j+Freemarker生成word文档

《Java利用docx4j+Freemarker生成word文档》这篇文章主要为大家详细介绍了Java如何利用docx4j+Freemarker生成word文档,文中的示例代码讲解详细,感兴趣的小伙伴... 目录技术方案maven依赖创建模板文件实现代码技术方案Java 1.8 + docx4j + Fr

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable