mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
fix code
This commit is contained in:
parent
ed0b9a16ef
commit
9461336639
@ -23,6 +23,7 @@ public class Connector {
|
||||
private String user = "root";
|
||||
private String password;
|
||||
private String group;
|
||||
private long timeout;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
@ -52,10 +53,24 @@ public class Connector {
|
||||
* @param password 密码
|
||||
*/
|
||||
public Connector(final String host, final int port, final String user, final String password) {
|
||||
this(host, port, user, password, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param host 主机名
|
||||
* @param port 端口
|
||||
* @param user 用户名
|
||||
* @param password 密码
|
||||
* @param timeout 连接超时时长,0表示默认
|
||||
*/
|
||||
public Connector(final String host, final int port, final String user, final String password, final long timeout) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.user = user;
|
||||
this.password = password;
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,11 +163,36 @@ public class Connector {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得连接超时时间
|
||||
*
|
||||
* @return 连接超时时间
|
||||
*/
|
||||
public long getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置连接超时时间
|
||||
*
|
||||
* @param timeout 连接超时时间
|
||||
*/
|
||||
public void setTimeout(final long timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* toString方法仅用于测试显示
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Connector [host=" + host + ", port=" + port + ", user=" + user + ", password=" + password + "]";
|
||||
return "Connector{" +
|
||||
"host='" + host + '\'' +
|
||||
", port=" + port +
|
||||
", user='" + user + '\'' +
|
||||
", password='" + password + '\'' +
|
||||
", group='" + group + '\'' +
|
||||
", timeout=" + timeout +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -13,16 +13,22 @@
|
||||
package org.dromara.hutool.extra.ssh.engine.ganymed;
|
||||
|
||||
import ch.ethz.ssh2.Connection;
|
||||
import ch.ethz.ssh2.LocalPortForwarder;
|
||||
import ch.ethz.ssh2.StreamGobbler;
|
||||
import org.dromara.hutool.core.io.IORuntimeException;
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.map.MapUtil;
|
||||
import org.dromara.hutool.core.net.Ipv4Util;
|
||||
import org.dromara.hutool.core.util.CharsetUtil;
|
||||
import org.dromara.hutool.extra.ssh.Connector;
|
||||
import org.dromara.hutool.extra.ssh.Session;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* {@link ch.ethz.ssh2.Session}包装
|
||||
@ -31,15 +37,28 @@ import java.nio.charset.Charset;
|
||||
*/
|
||||
public class GanymedSession implements Session {
|
||||
|
||||
private Connection connection;
|
||||
private final ch.ethz.ssh2.Session raw;
|
||||
|
||||
private Map<Integer, LocalPortForwarder> localPortForwarderMap;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param connector {@link Connector},保存连接和验证信息等
|
||||
*/
|
||||
public GanymedSession(final Connector connector) {
|
||||
this(openSession(connector));
|
||||
this(GanymedUtil.openConnection(connector));
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param connection {@link Connection},连接对象
|
||||
*/
|
||||
public GanymedSession(final Connection connection) {
|
||||
this(GanymedUtil.openSession(connection));
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,7 +66,7 @@ public class GanymedSession implements Session {
|
||||
*
|
||||
* @param raw {@link ch.ethz.ssh2.Session}
|
||||
*/
|
||||
public GanymedSession(final ch.ethz.ssh2.Session raw) {
|
||||
private GanymedSession(final ch.ethz.ssh2.Session raw) {
|
||||
this.raw = raw;
|
||||
}
|
||||
|
||||
@ -61,6 +80,104 @@ public class GanymedSession implements Session {
|
||||
if (raw != null) {
|
||||
raw.close();
|
||||
}
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定端口到本地。 一个会话可绑定多个端口
|
||||
*
|
||||
* @param remoteHost 远程主机
|
||||
* @param remotePort 远程端口
|
||||
* @param localPort 本地端口
|
||||
* @return 成功与否
|
||||
* @throws IORuntimeException 端口绑定失败异常
|
||||
*/
|
||||
public boolean bindLocalPort(final String remoteHost, final int remotePort, final int localPort) throws IORuntimeException {
|
||||
return bindLocalPort(remoteHost, remotePort, Ipv4Util.LOCAL_IP, localPort);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定端口到本地。 一个会话可绑定多个端口
|
||||
*
|
||||
* @param remoteHost 远程主机
|
||||
* @param remotePort 远程端口
|
||||
* @param localHost 本地主机
|
||||
* @param localPort 本地端口
|
||||
* @return 成功与否
|
||||
* @throws IORuntimeException 端口绑定失败异常
|
||||
*/
|
||||
public boolean bindLocalPort(final String remoteHost, final int remotePort, final String localHost, final int localPort) throws IORuntimeException {
|
||||
final LocalPortForwarder localPortForwarder;
|
||||
try {
|
||||
localPortForwarder = this.connection.createLocalPortForwarder(new InetSocketAddress(localHost, localPort), remoteHost, remotePort);
|
||||
} catch (final IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
|
||||
if(null == this.localPortForwarderMap){
|
||||
this.localPortForwarderMap = new HashMap<>();
|
||||
}
|
||||
|
||||
//加入记录
|
||||
this.localPortForwarderMap.put(localPort, localPortForwarder);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解除本地端口映射
|
||||
*
|
||||
* @param localPort 需要解除的本地端口
|
||||
* @throws IORuntimeException 端口解绑失败异常
|
||||
*/
|
||||
public void unBindLocalPort(final int localPort) throws IORuntimeException {
|
||||
if(MapUtil.isEmpty(this.localPortForwarderMap)){
|
||||
return;
|
||||
}
|
||||
|
||||
final LocalPortForwarder localPortForwarder = this.localPortForwarderMap.remove(localPort);
|
||||
if(null != localPortForwarder){
|
||||
try {
|
||||
localPortForwarder.close();
|
||||
} catch (final IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定ssh服务端的serverPort端口, 到host主机的port端口上. <br>
|
||||
* 即数据从ssh服务端的serverPort端口, 流经ssh客户端, 达到host:port上.
|
||||
*
|
||||
* @param bindPort ssh服务端上要被绑定的端口
|
||||
* @param host 转发到的host
|
||||
* @param port host上的端口
|
||||
* @return 成功与否
|
||||
* @throws IORuntimeException 端口绑定失败异常
|
||||
*/
|
||||
public boolean bindRemotePort(final int bindPort, final String host, final int port) throws IORuntimeException {
|
||||
try {
|
||||
this.connection.requestRemotePortForwarding(Ipv4Util.LOCAL_IP, bindPort, host, port);
|
||||
} catch (final IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解除远程端口映射
|
||||
*
|
||||
* @param localPort 需要解除的本地端口
|
||||
* @throws IORuntimeException 端口解绑失败异常
|
||||
*/
|
||||
public void unBindRemotePort(final int localPort) throws IORuntimeException {
|
||||
try {
|
||||
this.connection.cancelRemotePortForwarding(localPort);
|
||||
} catch (final IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,7 +204,7 @@ public class GanymedSession implements Session {
|
||||
}
|
||||
|
||||
// 错误输出
|
||||
if(null != errStream){
|
||||
if (null != errStream) {
|
||||
IoUtil.copy(new StreamGobbler(this.raw.getStderr()), errStream);
|
||||
}
|
||||
|
||||
@ -128,29 +245,4 @@ public class GanymedSession implements Session {
|
||||
// 结果输出
|
||||
return IoUtil.read(new StreamGobbler(this.raw.getStdout()), charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化并打开新的Session
|
||||
*
|
||||
* @param connector {@link Connector},保存连接和验证信息等
|
||||
* @return {@link ch.ethz.ssh2.Session}
|
||||
*/
|
||||
private static ch.ethz.ssh2.Session openSession(final Connector connector) {
|
||||
|
||||
// 建立连接
|
||||
final Connection conn = new Connection(connector.getHost(), connector.getPort());
|
||||
try {
|
||||
conn.connect();
|
||||
} catch (final IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
|
||||
// 打开会话
|
||||
try {
|
||||
conn.authenticateWithPassword(connector.getUser(), connector.getPassword());
|
||||
return conn.openSession();
|
||||
} catch (final IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.extra.ssh.engine.ganymed;
|
||||
|
||||
import ch.ethz.ssh2.Connection;
|
||||
import ch.ethz.ssh2.Session;
|
||||
import org.dromara.hutool.core.io.IORuntimeException;
|
||||
import org.dromara.hutool.extra.ssh.Connector;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Ganymed-ssh2相关工具类
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
public class GanymedUtil {
|
||||
|
||||
/**
|
||||
* 打开SSH连接
|
||||
*
|
||||
* @param connector 连接信息
|
||||
* @return {@link Connection}
|
||||
*/
|
||||
public static Connection openConnection(final Connector connector) {
|
||||
// 建立连接
|
||||
final Connection conn = new Connection(connector.getHost(), connector.getPort());
|
||||
try {
|
||||
conn.connect();
|
||||
} catch (final IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
|
||||
// 验证
|
||||
final boolean isAuth;
|
||||
try {
|
||||
isAuth = conn.authenticateWithPassword(connector.getUser(), connector.getPassword());
|
||||
} catch (final IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
|
||||
if(!isAuth){
|
||||
throw new IORuntimeException("Authentication failed.");
|
||||
}
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开SSH会话
|
||||
*
|
||||
* @param connection 连接对象
|
||||
* @return {@link Session}
|
||||
*/
|
||||
public static Session openSession(final Connection connection) {
|
||||
// 打开会话
|
||||
try {
|
||||
return connection.openSession();
|
||||
} catch (final IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ package org.dromara.hutool.extra.ssh.engine.jsch;
|
||||
import com.jcraft.jsch.*;
|
||||
import org.dromara.hutool.core.io.IORuntimeException;
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.net.Ipv4Util;
|
||||
import org.dromara.hutool.core.util.ByteUtil;
|
||||
import org.dromara.hutool.core.util.CharsetUtil;
|
||||
import org.dromara.hutool.extra.ssh.Connector;
|
||||
@ -32,6 +33,7 @@ import java.nio.charset.Charset;
|
||||
public class JschSession implements Session {
|
||||
|
||||
private final com.jcraft.jsch.Session raw;
|
||||
private final long timeout;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
@ -39,28 +41,51 @@ public class JschSession implements Session {
|
||||
* @param connector {@link Connector},保存连接和验证信息等
|
||||
*/
|
||||
public JschSession(final Connector connector) {
|
||||
this(openSession(connector));
|
||||
this(JschUtil.openSession(connector), connector.getTimeout());
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param raw {@link com.jcraft.jsch.Session}
|
||||
* @param raw {@link com.jcraft.jsch.Session}
|
||||
* @param timeout 连接超时时常,0表示不限制
|
||||
*/
|
||||
public JschSession(final com.jcraft.jsch.Session raw) {
|
||||
public JschSession(final com.jcraft.jsch.Session raw, final long timeout) {
|
||||
this.raw = raw;
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRaw() {
|
||||
return raw;
|
||||
public com.jcraft.jsch.Session getRaw() {
|
||||
return this.raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否连接状态
|
||||
*
|
||||
* @return 是否连接状态
|
||||
*/
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
public boolean isConnected() {
|
||||
return null != this.raw && this.raw.isConnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (raw != null && raw.isConnected()) {
|
||||
raw.disconnect();
|
||||
}
|
||||
JschUtil.close(this.raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定端口到本地。 一个会话可绑定多个端口
|
||||
*
|
||||
* @param remoteHost 远程主机
|
||||
* @param remotePort 远程端口
|
||||
* @param localPort 本地端口
|
||||
* @return 成功与否
|
||||
* @throws SshException 端口绑定失败异常
|
||||
*/
|
||||
public boolean bindLocalPort(final String remoteHost, final int remotePort, final int localPort) throws SshException {
|
||||
return bindLocalPort(remoteHost, remotePort, Ipv4Util.LOCAL_IP, localPort);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,16 +98,30 @@ public class JschSession implements Session {
|
||||
* @return 成功与否
|
||||
* @throws SshException 端口绑定失败异常
|
||||
*/
|
||||
public boolean bindPort(final String remoteHost, final int remotePort, final String localHost, final int localPort) throws SshException {
|
||||
if (this.raw != null && this.raw.isConnected()) {
|
||||
try {
|
||||
this.raw.setPortForwardingL(localHost, localPort, remoteHost, remotePort);
|
||||
} catch (final JSchException e) {
|
||||
throw new SshException(e, "From [{}:{}] mapping to [{}:{}] error!", remoteHost, remotePort, localHost, localPort);
|
||||
}
|
||||
return true;
|
||||
public boolean bindLocalPort(final String remoteHost, final int remotePort, final String localHost, final int localPort) throws SshException {
|
||||
if (!isConnected()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
this.raw.setPortForwardingL(localHost, localPort, remoteHost, remotePort);
|
||||
} catch (final JSchException e) {
|
||||
throw new SshException(e, "From [{}:{}] mapping to [{}:{}] error!", remoteHost, remotePort, localHost, localPort);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解除远程端口映射
|
||||
*
|
||||
* @param localPort 需要解除的本地端口
|
||||
*/
|
||||
public void unBindLocalPort(final int localPort) {
|
||||
try {
|
||||
this.raw.delPortForwardingL(localPort);
|
||||
} catch (final JSchException e) {
|
||||
throw new SshException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -96,25 +135,26 @@ public class JschSession implements Session {
|
||||
* @throws SshException 端口绑定失败异常
|
||||
*/
|
||||
public boolean bindRemotePort(final int bindPort, final String host, final int port) throws SshException {
|
||||
if (this.raw != null && this.raw.isConnected()) {
|
||||
try {
|
||||
this.raw.setPortForwardingR(bindPort, host, port);
|
||||
} catch (final JSchException e) {
|
||||
throw new SshException(e, "From [{}] mapping to [{}] error!", bindPort, port);
|
||||
}
|
||||
return true;
|
||||
if (!isConnected()) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
try {
|
||||
this.raw.setPortForwardingR(bindPort, host, port);
|
||||
} catch (final JSchException e) {
|
||||
throw new SshException(e, "From [{}] mapping to [{}] error!", bindPort, port);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解除端口映射
|
||||
* 解除远程端口映射
|
||||
*
|
||||
* @param localPort 需要解除的本地端口
|
||||
*/
|
||||
public void unBindPort(final int localPort) {
|
||||
public void unBindRemotePort(final int localPort) {
|
||||
try {
|
||||
this.raw.delPortForwardingL(localPort);
|
||||
this.raw.delPortForwardingR(localPort);
|
||||
} catch (final JSchException e) {
|
||||
throw new SshException(e);
|
||||
}
|
||||
@ -127,16 +167,7 @@ public class JschSession implements Session {
|
||||
* @return {@link Channel}
|
||||
*/
|
||||
public Channel createChannel(final ChannelType channelType) {
|
||||
final Channel channel;
|
||||
try {
|
||||
if (!this.raw.isConnected()) {
|
||||
this.raw.connect();
|
||||
}
|
||||
channel = this.raw.openChannel(channelType.getValue());
|
||||
} catch (final JSchException e) {
|
||||
throw new SshException(e);
|
||||
}
|
||||
return channel;
|
||||
return JschUtil.createChannel(this.raw, channelType, this.timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -155,24 +186,17 @@ public class JschSession implements Session {
|
||||
* @return {@link Channel}
|
||||
*/
|
||||
public Channel openChannel(final ChannelType channelType) {
|
||||
return openChannel(channelType, 0);
|
||||
return JschUtil.openChannel(this.raw, channelType, this.timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开Channel连接
|
||||
* 打开SFTP会话
|
||||
*
|
||||
* @param channelType 通道类型,可以是shell或sftp等,见{@link ChannelType}
|
||||
* @param timeout 连接超时时长,单位毫秒
|
||||
* @return {@link Channel}
|
||||
* @param charset 编码
|
||||
* @return {@link JschSftp}
|
||||
*/
|
||||
public Channel openChannel(final ChannelType channelType, final int timeout) {
|
||||
final Channel channel = createChannel(channelType);
|
||||
try {
|
||||
channel.connect(Math.max(timeout, 0));
|
||||
} catch (final JSchException e) {
|
||||
throw new SshException(e);
|
||||
}
|
||||
return channel;
|
||||
public JschSftp openSftp(final Charset charset) {
|
||||
return new JschSftp(this.raw, charset, this.timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -259,26 +283,4 @@ public class JschSession implements Session {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建{@link com.jcraft.jsch.Session}
|
||||
*
|
||||
* @param connector {@link Connector},保存连接和验证信息等
|
||||
* @return {@link com.jcraft.jsch.Session}
|
||||
*/
|
||||
private static com.jcraft.jsch.Session openSession(final Connector connector) {
|
||||
final JSch jsch = new JSch();
|
||||
final com.jcraft.jsch.Session session;
|
||||
try {
|
||||
session = jsch.getSession(connector.getUser(), connector.getHost(), connector.getPort());
|
||||
} catch (final JSchException e) {
|
||||
throw new SshException(e);
|
||||
}
|
||||
|
||||
session.setPassword(connector.getPassword());
|
||||
// 设置第一次登录的时候提示,可选值:(ask | yes | no)
|
||||
session.setConfig("StrictHostKeyChecking", "no");
|
||||
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
package org.dromara.hutool.extra.ssh.engine.jsch;
|
||||
|
||||
import com.jcraft.jsch.*;
|
||||
import org.dromara.hutool.core.collection.CollUtil;
|
||||
import org.dromara.hutool.core.collection.ListUtil;
|
||||
import org.dromara.hutool.core.io.file.FileUtil;
|
||||
@ -19,13 +20,9 @@ import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.extra.ftp.AbstractFtp;
|
||||
import org.dromara.hutool.extra.ftp.FtpConfig;
|
||||
import org.dromara.hutool.extra.ftp.FtpException;
|
||||
import com.jcraft.jsch.ChannelSftp;
|
||||
import com.jcraft.jsch.ChannelSftp.LsEntry;
|
||||
import com.jcraft.jsch.ChannelSftp.LsEntrySelector;
|
||||
import com.jcraft.jsch.Session;
|
||||
import com.jcraft.jsch.SftpATTRS;
|
||||
import com.jcraft.jsch.SftpException;
|
||||
import com.jcraft.jsch.SftpProgressMonitor;
|
||||
import org.dromara.hutool.extra.ssh.Connector;
|
||||
import org.dromara.hutool.extra.ssh.SshException;
|
||||
|
||||
import java.io.File;
|
||||
@ -50,7 +47,7 @@ import java.util.function.Predicate;
|
||||
* @author looly
|
||||
* @since 4.0.2
|
||||
*/
|
||||
public class Sftp extends AbstractFtp {
|
||||
public class JschSftp extends AbstractFtp {
|
||||
|
||||
private Session session;
|
||||
private ChannelSftp channel;
|
||||
@ -65,7 +62,7 @@ public class Sftp extends AbstractFtp {
|
||||
* @param sshUser 远程主机用户名
|
||||
* @param sshPass 远程主机密码
|
||||
*/
|
||||
public Sftp(final String sshHost, final int sshPort, final String sshUser, final String sshPass) {
|
||||
public JschSftp(final String sshHost, final int sshPort, final String sshUser, final String sshPass) {
|
||||
this(sshHost, sshPort, sshUser, sshPass, DEFAULT_CHARSET);
|
||||
}
|
||||
|
||||
@ -79,7 +76,7 @@ public class Sftp extends AbstractFtp {
|
||||
* @param charset 编码
|
||||
* @since 4.1.14
|
||||
*/
|
||||
public Sftp(final String sshHost, final int sshPort, final String sshUser, final String sshPass, final Charset charset) {
|
||||
public JschSftp(final String sshHost, final int sshPort, final String sshUser, final String sshPass, final Charset charset) {
|
||||
this(new FtpConfig(sshHost, sshPort, sshUser, sshPass, charset));
|
||||
}
|
||||
|
||||
@ -89,7 +86,7 @@ public class Sftp extends AbstractFtp {
|
||||
* @param config FTP配置
|
||||
* @since 5.3.3
|
||||
*/
|
||||
public Sftp(final FtpConfig config) {
|
||||
public JschSftp(final FtpConfig config) {
|
||||
this(config, true);
|
||||
}
|
||||
|
||||
@ -100,45 +97,13 @@ public class Sftp extends AbstractFtp {
|
||||
* @param init 是否立即初始化
|
||||
* @since 5.8.4
|
||||
*/
|
||||
public Sftp(final FtpConfig config, final boolean init) {
|
||||
public JschSftp(final FtpConfig config, final boolean init) {
|
||||
super(config);
|
||||
if (init) {
|
||||
init(config);
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param session {@link Session}
|
||||
*/
|
||||
public Sftp(final Session session) {
|
||||
this(session, DEFAULT_CHARSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param session {@link Session}
|
||||
* @param charset 编码
|
||||
* @since 4.1.14
|
||||
*/
|
||||
public Sftp(final Session session, final Charset charset) {
|
||||
super(FtpConfig.of().setCharset(charset));
|
||||
init(session, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param channel {@link ChannelSftp}
|
||||
* @param charset 编码
|
||||
*/
|
||||
public Sftp(final ChannelSftp channel, final Charset charset) {
|
||||
super(FtpConfig.of().setCharset(charset));
|
||||
init(channel, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
@ -147,9 +112,10 @@ public class Sftp extends AbstractFtp {
|
||||
* @param timeOut 超时时间,单位毫秒
|
||||
* @since 5.8.4
|
||||
*/
|
||||
public Sftp(final Session session, final Charset charset, final long timeOut) {
|
||||
public JschSftp(final Session session, final Charset charset, final long timeOut) {
|
||||
super(FtpConfig.of().setCharset(charset).setConnectionTimeout(timeOut));
|
||||
init(session, charset);
|
||||
this.session = session;
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,73 +126,49 @@ public class Sftp extends AbstractFtp {
|
||||
* @param timeOut 超时时间,单位毫秒
|
||||
* @since 5.8.4
|
||||
*/
|
||||
public Sftp(final ChannelSftp channel, final Charset charset, final long timeOut) {
|
||||
public JschSftp(final ChannelSftp channel, final Charset charset, final long timeOut) {
|
||||
super(FtpConfig.of().setCharset(charset).setConnectionTimeout(timeOut));
|
||||
init(channel, charset);
|
||||
this.channel = channel;
|
||||
init();
|
||||
}
|
||||
// ---------------------------------------------------------------------------------------- Constructor end
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param sshHost 远程主机
|
||||
* @param sshPort 远程主机端口
|
||||
* @param sshUser 远程主机用户名
|
||||
* @param sshPass 远程主机密码
|
||||
* @param charset 编码
|
||||
*/
|
||||
public void init(final String sshHost, final int sshPort, final String sshUser, final String sshPass, final Charset charset) {
|
||||
init(JschUtil.getSession(sshHost, sshPort, sshUser, sshPass), charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @since 5.3.3
|
||||
*/
|
||||
@SuppressWarnings("resource")
|
||||
public void init() {
|
||||
init(this.ftpConfig);
|
||||
}
|
||||
if(null == this.channel){
|
||||
if(null == this.session){
|
||||
final FtpConfig config = this.ftpConfig;
|
||||
this.session = new JschSession(new Connector(
|
||||
config.getHost(),
|
||||
config.getPort(),
|
||||
config.getUser(),
|
||||
config.getPassword(),
|
||||
config.getConnectionTimeout()))
|
||||
.getRaw();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @param config FTP配置
|
||||
* @since 5.3.3
|
||||
*/
|
||||
public void init(final FtpConfig config) {
|
||||
init(config.getHost(), config.getPort(), config.getUser(), config.getPassword(), config.getCharset());
|
||||
}
|
||||
// 创建Channel
|
||||
try {
|
||||
this.channel = (ChannelSftp) this.session.openChannel(ChannelType.SFTP.getValue());
|
||||
} catch (final JSchException e) {
|
||||
throw new SshException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @param session {@link Session}
|
||||
* @param charset 编码
|
||||
*/
|
||||
public void init(final Session session, final Charset charset) {
|
||||
this.session = session;
|
||||
init(JschUtil.openSftp(session, (int) this.ftpConfig.getConnectionTimeout()), charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @param channel {@link ChannelSftp}
|
||||
* @param charset 编码
|
||||
*/
|
||||
public void init(final ChannelSftp channel, final Charset charset) {
|
||||
this.ftpConfig.setCharset(charset);
|
||||
try {
|
||||
channel.setFilenameEncoding(charset.toString());
|
||||
} catch (final SftpException e) {
|
||||
if(!channel.isConnected()){
|
||||
channel.connect((int) Math.max(this.ftpConfig.getConnectionTimeout(), 0));
|
||||
}
|
||||
channel.setFilenameEncoding(this.ftpConfig.getCharset().toString());
|
||||
} catch (final JSchException | SftpException e) {
|
||||
throw new SshException(e);
|
||||
}
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sftp reconnectIfTimeout() {
|
||||
public JschSftp reconnectIfTimeout() {
|
||||
if (StrUtil.isBlank(this.ftpConfig.getHost())) {
|
||||
throw new FtpException("Host is blank!");
|
||||
}
|
||||
@ -554,7 +496,7 @@ public class Sftp extends AbstractFtp {
|
||||
* @param destPath 目标路径,
|
||||
* @return this
|
||||
*/
|
||||
public Sftp put(final String srcFilePath, final String destPath) {
|
||||
public JschSftp put(final String srcFilePath, final String destPath) {
|
||||
return put(srcFilePath, destPath, Mode.OVERWRITE);
|
||||
}
|
||||
|
||||
@ -566,7 +508,7 @@ public class Sftp extends AbstractFtp {
|
||||
* @param mode {@link Mode} 模式
|
||||
* @return this
|
||||
*/
|
||||
public Sftp put(final String srcFilePath, final String destPath, final Mode mode) {
|
||||
public JschSftp put(final String srcFilePath, final String destPath, final Mode mode) {
|
||||
return put(srcFilePath, destPath, null, mode);
|
||||
}
|
||||
|
||||
@ -580,7 +522,7 @@ public class Sftp extends AbstractFtp {
|
||||
* @return this
|
||||
* @since 4.6.5
|
||||
*/
|
||||
public Sftp put(final String srcFilePath, final String destPath, final SftpProgressMonitor monitor, final Mode mode) {
|
||||
public JschSftp put(final String srcFilePath, final String destPath, final SftpProgressMonitor monitor, final Mode mode) {
|
||||
try {
|
||||
getClient().put(srcFilePath, destPath, monitor, mode.ordinal());
|
||||
} catch (final SftpException e) {
|
||||
@ -599,7 +541,7 @@ public class Sftp extends AbstractFtp {
|
||||
* @return this
|
||||
* @since 5.7.16
|
||||
*/
|
||||
public Sftp put(final InputStream srcStream, final String destPath, final SftpProgressMonitor monitor, final Mode mode) {
|
||||
public JschSftp put(final InputStream srcStream, final String destPath, final SftpProgressMonitor monitor, final Mode mode) {
|
||||
try {
|
||||
getClient().put(srcStream, destPath, monitor, mode.ordinal());
|
||||
} catch (final SftpException e) {
|
||||
@ -662,7 +604,7 @@ public class Sftp extends AbstractFtp {
|
||||
* @param dest 目标文件路径
|
||||
* @return this
|
||||
*/
|
||||
public Sftp get(final String src, final String dest) {
|
||||
public JschSftp get(final String src, final String dest) {
|
||||
try {
|
||||
getClient().get(src, dest);
|
||||
} catch (final SftpException e) {
|
||||
@ -679,7 +621,7 @@ public class Sftp extends AbstractFtp {
|
||||
* @return this
|
||||
* @since 5.7.0
|
||||
*/
|
||||
public Sftp get(final String src, final OutputStream out) {
|
||||
public JschSftp get(final String src, final OutputStream out) {
|
||||
try {
|
||||
getClient().get(src, out);
|
||||
} catch (final SftpException e) {
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.extra.ssh.engine.jsch;
|
||||
|
||||
import com.jcraft.jsch.Channel;
|
||||
import com.jcraft.jsch.JSch;
|
||||
import com.jcraft.jsch.JSchException;
|
||||
import com.jcraft.jsch.Session;
|
||||
import org.dromara.hutool.extra.ssh.Connector;
|
||||
import org.dromara.hutool.extra.ssh.SshException;
|
||||
|
||||
/**
|
||||
* Jsch工具类<br>
|
||||
* Jsch是Java Secure Channel的缩写。JSch是一个SSH2的纯Java实现。<br>
|
||||
* 它允许你连接到一个SSH服务器,并且可以使用端口转发,X11转发,文件传输等。<br>
|
||||
*
|
||||
* @author Looly
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class JschUtil {
|
||||
|
||||
/**
|
||||
* 打开Session会话
|
||||
* @param connector 连接信息
|
||||
* @return {@link JschSession}
|
||||
*/
|
||||
public static Session openSession(final Connector connector){
|
||||
final JSch jsch = new JSch();
|
||||
final com.jcraft.jsch.Session session;
|
||||
try {
|
||||
session = jsch.getSession(connector.getUser(), connector.getHost(), connector.getPort());
|
||||
session.setTimeout((int) connector.getTimeout());
|
||||
} catch (final JSchException e) {
|
||||
throw new SshException(e);
|
||||
}
|
||||
|
||||
session.setPassword(connector.getPassword());
|
||||
// 设置第一次登录的时候提示,可选值:(ask | yes | no)
|
||||
session.setConfig("StrictHostKeyChecking", "no");
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开Channel连接
|
||||
*
|
||||
* @param session Session会话
|
||||
* @param channelType 通道类型,可以是shell或sftp等,见{@link ChannelType}
|
||||
* @param timeout 连接超时时长,单位毫秒
|
||||
* @return {@link Channel}
|
||||
* @since 5.3.3
|
||||
*/
|
||||
public static Channel openChannel(final Session session, final ChannelType channelType, final long timeout) {
|
||||
final Channel channel = createChannel(session, channelType, timeout);
|
||||
try {
|
||||
channel.connect((int) Math.max(timeout, 0));
|
||||
} catch (final JSchException e) {
|
||||
throw new SshException(e);
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Channel连接
|
||||
*
|
||||
* @param session Session会话
|
||||
* @param channelType 通道类型,可以是shell或sftp等,见{@link ChannelType}
|
||||
* @param timeout session超时时常,单位:毫秒
|
||||
* @return {@link Channel}
|
||||
* @since 4.5.2
|
||||
*/
|
||||
public static Channel createChannel(final Session session, final ChannelType channelType, final long timeout) {
|
||||
final Channel channel;
|
||||
try {
|
||||
if (false == session.isConnected()) {
|
||||
session.connect((int) timeout);
|
||||
}
|
||||
channel = session.openChannel(channelType.getValue());
|
||||
} catch (final JSchException e) {
|
||||
throw new SshException(e);
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭SSH连接会话
|
||||
*
|
||||
* @param session SSH会话
|
||||
*/
|
||||
public static void close(final Session session) {
|
||||
if (session != null && session.isConnected()) {
|
||||
session.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭会话通道
|
||||
*
|
||||
* @param channel 会话通道
|
||||
* @since 4.0.3
|
||||
*/
|
||||
public static void close(final Channel channel) {
|
||||
if (channel != null && channel.isConnected()) {
|
||||
channel.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
@ -13,7 +13,6 @@
|
||||
package org.dromara.hutool.extra.ssh.engine.sshj;
|
||||
|
||||
import net.schmizz.sshj.SSHClient;
|
||||
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;
|
||||
import org.dromara.hutool.core.io.IORuntimeException;
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.util.CharsetUtil;
|
||||
@ -40,17 +39,21 @@ public class SshjSession implements Session {
|
||||
* @param connector {@link Connector},保存连接和验证信息等
|
||||
*/
|
||||
public SshjSession(final Connector connector) {
|
||||
final SSHClient ssh = new SSHClient();
|
||||
ssh.addHostKeyVerifier(new PromiscuousVerifier());
|
||||
this(SshjUtil.openClient(connector));
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param ssh {@link SSHClient}
|
||||
*/
|
||||
public SshjSession(final SSHClient ssh) {
|
||||
this.ssh = ssh;
|
||||
try {
|
||||
ssh.connect(connector.getHost(), connector.getPort());
|
||||
ssh.authPassword(connector.getUser(), connector.getPassword());
|
||||
this.raw = ssh.startSession();
|
||||
} catch (final IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
|
||||
this.ssh = ssh;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,10 +66,19 @@ public class SshjSession implements Session {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRaw() {
|
||||
public net.schmizz.sshj.connection.channel.direct.Session getRaw() {
|
||||
return raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否连接状态
|
||||
*
|
||||
* @return 是否连接状态
|
||||
*/
|
||||
public boolean isConnected() {
|
||||
return null != this.raw && (null == this.ssh || this.ssh.isConnected());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
IoUtil.closeQuietly(this.raw);
|
||||
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.extra.ssh.engine.sshj;
|
||||
|
||||
import net.schmizz.sshj.SSHClient;
|
||||
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;
|
||||
import org.dromara.hutool.core.io.IORuntimeException;
|
||||
import org.dromara.hutool.extra.ssh.Connector;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 基于SSHJ(https://github.com/hierynomus/sshj)相关工具类
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
public class SshjUtil {
|
||||
|
||||
/**
|
||||
* 打开客户端连接
|
||||
*
|
||||
* @param connector 连接信息
|
||||
* @return {@link SSHClient}
|
||||
*/
|
||||
public static SSHClient openClient(final Connector connector) {
|
||||
final SSHClient ssh = new SSHClient();
|
||||
ssh.addHostKeyVerifier(new PromiscuousVerifier());
|
||||
ssh.setConnectTimeout((int) connector.getTimeout());
|
||||
ssh.setTimeout((int) connector.getTimeout());
|
||||
|
||||
try {
|
||||
ssh.connect(connector.getHost(), connector.getPort());
|
||||
ssh.authPassword(connector.getUser(), connector.getPassword());
|
||||
} catch (final IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
|
||||
return ssh;
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ import org.apache.commons.net.ftp.FTPSClient;
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.io.file.FileUtil;
|
||||
import org.dromara.hutool.core.lang.Console;
|
||||
import org.dromara.hutool.extra.ssh.engine.jsch.Sftp;
|
||||
import org.dromara.hutool.extra.ssh.engine.jsch.JschSftp;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@ -94,7 +94,7 @@ public class FtpTest {
|
||||
@Test
|
||||
@Disabled
|
||||
public void recursiveDownloadFolderSftp() {
|
||||
final Sftp ftp = new Sftp("127.0.0.1", 22, "test", "test");
|
||||
final JschSftp ftp = new JschSftp("127.0.0.1", 22, "test", "test");
|
||||
|
||||
ftp.cd("/file/aaa");
|
||||
Console.log(ftp.pwd());
|
||||
@ -131,7 +131,7 @@ public class FtpTest {
|
||||
@Test
|
||||
@Disabled
|
||||
public void existSftpTest() {
|
||||
try (final Sftp ftp = new Sftp("127.0.0.1", 22, "test", "test")) {
|
||||
try (final JschSftp ftp = new JschSftp("127.0.0.1", 22, "test", "test")) {
|
||||
Console.log(ftp.pwd());
|
||||
Console.log(ftp.exist(null));
|
||||
Console.log(ftp.exist(""));
|
||||
|
@ -14,9 +14,9 @@ package org.dromara.hutool.extra.ssh;
|
||||
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.lang.Console;
|
||||
import com.jcraft.jsch.Session;
|
||||
import org.dromara.hutool.extra.ssh.engine.jsch.JschUtil;
|
||||
import org.dromara.hutool.extra.ssh.engine.jsch.Sftp;
|
||||
import org.dromara.hutool.core.util.CharsetUtil;
|
||||
import org.dromara.hutool.extra.ssh.engine.jsch.JschSession;
|
||||
import org.dromara.hutool.extra.ssh.engine.jsch.JschSftp;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -27,25 +27,26 @@ import org.junit.jupiter.api.Test;
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
public class JschUtilTest {
|
||||
public class JschTest {
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
@Test
|
||||
@Disabled
|
||||
public void bindPortTest() {
|
||||
//新建会话,此会话用于ssh连接到跳板机(堡垒机),此处为10.1.1.1:22
|
||||
final Session session = JschUtil.getSession("looly.centos", 22, "test", "123456");
|
||||
final JschSession session = new JschSession(new Connector("looly.centos", 22, "test", "123456"));
|
||||
// 将堡垒机保护的内网8080端口映射到localhost,我们就可以通过访问http://localhost:8080/访问内网服务了
|
||||
JschUtil.bindPort(session, "172.20.12.123", 8080, 8080);
|
||||
session.bindLocalPort("172.20.12.123", 8080, 8080);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
@Test
|
||||
@Disabled
|
||||
public void bindRemotePort() {
|
||||
// 建立会话
|
||||
final Session session = JschUtil.getSession("looly.centos", 22, "test", "123456");
|
||||
final JschSession session = new JschSession(new Connector("looly.centos", 22, "test", "123456"));
|
||||
// 绑定ssh服务端8089端口到本机的8000端口上
|
||||
final boolean b = JschUtil.bindRemotePort(session, 8089, "localhost", 8000);
|
||||
final boolean b = session.bindRemotePort(8089, "localhost", 8000);
|
||||
Assertions.assertTrue(b);
|
||||
// 保证一直运行
|
||||
}
|
||||
@ -54,43 +55,38 @@ public class JschUtilTest {
|
||||
@Test
|
||||
@Disabled
|
||||
public void sftpTest() {
|
||||
final Session session = JschUtil.getSession("looly.centos", 22, "root", "123456");
|
||||
final Sftp sftp = JschUtil.createSftp(session);
|
||||
sftp.mkDirs("/opt/test/aaa/bbb");
|
||||
final JschSession session = new JschSession(new Connector("looly.centos", 22, "root", "123456"));
|
||||
final JschSftp jschSftp = session.openSftp(CharsetUtil.UTF_8);
|
||||
jschSftp.mkDirs("/opt/test/aaa/bbb");
|
||||
Console.log("OK");
|
||||
}
|
||||
|
||||
@SuppressWarnings("CallToPrintStackTrace")
|
||||
@Test
|
||||
@Disabled
|
||||
public void reconnectIfTimeoutTest() throws InterruptedException {
|
||||
final Session session = JschUtil.getSession("sunnyserver", 22,"mysftp","liuyang1234");
|
||||
final Sftp sftp = JschUtil.createSftp(session);
|
||||
final JschSession session = new JschSession(new Connector("sunnyserver", 22,"mysftp","liuyang1234"));
|
||||
final JschSftp jschSftp = session.openSftp(CharsetUtil.UTF_8);
|
||||
|
||||
Console.log("打印pwd: " + sftp.pwd());
|
||||
Console.log("cd / : " + sftp.cd("/"));
|
||||
Console.log("打印pwd: " + jschSftp.pwd());
|
||||
Console.log("cd / : " + jschSftp.cd("/"));
|
||||
Console.log("休眠一段时间,查看是否超时");
|
||||
Thread.sleep(30 * 1000);
|
||||
|
||||
try{
|
||||
// 当连接超时时,isConnected()仍然返回true,pwd命令也能正常返回,因此,利用发送cd命令的返回结果,来判断是否连接超时
|
||||
Console.log("isConnected " + sftp.getClient().isConnected());
|
||||
Console.log("打印pwd: " + sftp.pwd());
|
||||
Console.log("cd / : " + sftp.cd("/"));
|
||||
Console.log("isConnected " + jschSftp.getClient().isConnected());
|
||||
Console.log("打印pwd: " + jschSftp.pwd());
|
||||
Console.log("cd / : " + jschSftp.cd("/"));
|
||||
}catch (final SshException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Console.log("调用reconnectIfTimeout方法,判断是否超时并重连");
|
||||
sftp.reconnectIfTimeout();
|
||||
jschSftp.reconnectIfTimeout();
|
||||
|
||||
Console.log("打印pwd: " + sftp.pwd());
|
||||
Console.log("打印pwd: " + jschSftp.pwd());
|
||||
|
||||
IoUtil.closeQuietly(sftp);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void getSessionTest(){
|
||||
JschUtil.getSession("192.168.1.134", 22, "root", "aaa", null);
|
||||
IoUtil.closeQuietly(jschSftp);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user