Java 实现 SCP 携带密码拷贝文件

背景说明

涉及通过程序进行机器间的文件Copy的场景,我们一般会使用ssh连接机器,通过scp命令进行文件copy。

此种方案的前提是:机器间事先要配置免密码互通。

但是 ,如果客户现场机器数量过多,配置免密操作比较麻烦;或者处于安全考虑,客户不允许机器之间免密访问。

此时,需要另辟蹊径,找其他方案实现。

需求场景:提供机器的IP,登录用户名、登录密码,但是不配置机器间的免密登录,实现机器之间的文件传输。

Java 实现

1、工具类

ScpUtil.java

java 复制代码
package com.miracle.luna.scp;

import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.scp.client.ScpClient;
import org.apache.sshd.scp.client.ScpClientCreator;

/**
 * @author Miracle Luna
 * @date 2021/7/19
 */
public class ScpUtil {

//    private static String host = "192.168.67.48";
    private static String host = "192.168.67.39";
//    private static String host = "192.168.71.29";
    private static String username = "root";
    private static String password = "password";
    private static Integer port = 22;

//    private static String local = "F:\\miracle\\*";
    private static String local = "/home/miracle/*";
    private static String remote = "/home/luna/";
//    private static String remote = "F:\\luna\\";

    public static void scpFile(String local, String remote) throws Exception {
        long startTime = System.currentTimeMillis();

        // 创建 SSH客户端
        SshClient client = SshClient.setUpDefaultClient();
        // 启动 SSH客户端
        client.start();
        // 通过主机IP、端口和用户名,连接主机,获取Session
        ClientSession session = client.connect(username, host, port).verify().getSession();
        // 给Session添加密码
        session.addPasswordIdentity(password);
        // 校验用户名和密码的有效性
        boolean isSuccess = session.auth().verify().isSuccess();

        // 认证成功
        if (isSuccess) {
            long middleTime = System.currentTimeMillis();
            System.out.println("Connect host cost time: " + (middleTime - startTime) / 1000.0 + "s.");

            ScpClientCreator creator = ScpClientCreator.instance();
            // 创建 SCP 客户端
            ScpClient scpClient = creator.createScpClient(session);

            System.out.println("Scp beginning.");
            // ScpClient.Option.Recursive:递归copy,可以将子文件夹和子文件遍历copy
            scpClient.upload(local, remote, ScpClient.Option.Recursive);
            System.out.println("Scp finished.");

            // 释放 SCP客户端
            if (scpClient != null) {
                scpClient = null;
            }

            // 关闭 Session
            if (session != null && session.isOpen()) {
                session.close();
            }

            // 关闭 SSH客户端
            if (client != null && client.isOpen()) {
                client.stop();
                client.close();
            }
        }

        long endTime = System.currentTimeMillis();
        System.out.println("Total Cost time: " + (endTime - startTime) / 1000.0 + "s.");
    }

    public static void main(String[] args) throws Exception {
        scpFile(local, remote);
    }
}

2、运行结果

java 复制代码
Connect host cost time: 6.519s.
Scp beginning.
Scp finished.
Total Cost time: 9.569s.

3、Maven依赖

xml 复制代码
<!-- https://mvnrepository.com/artifact/org.apache.sshd/sshd-common -->
<dependency>
    <groupId>org.apache.sshd</groupId>
    <artifactId>sshd-common</artifactId>
    <version>2.7.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.sshd/sshd-core -->
<dependency>
    <groupId>org.apache.sshd</groupId>
    <artifactId>sshd-core</artifactId>
    <version>2.7.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.sshd/sshd-scp -->
<dependency>
    <groupId>org.apache.sshd</groupId>
    <artifactId>sshd-scp</artifactId>
    <version>2.7.0</version>
</dependency>

补充说明

该方式适用于Linux到Linux、Linux到Windows、Windows到Linux、Windows到Windows间的文件拷贝。

(和Windows进行文件交互的前提是:Windows安装了SSH服务端,如OpenSSH,FreeSSHd,Bitvise SSH Server等)

相关推荐
老白干14 分钟前
jjwt 0.9.1 在 JDK 11+ 上的两个“坑”与完整解决方案
java·python·log4j
圆山猫7 小时前
[Virtualization](四):Linux KVM/RISC-V 的 vCPU 运行路径
java·linux·risc-v
城管不管7 小时前
ReAct、Plan-and-Execute、Reflection 三大智能 Agent 范式核心区别
java·人工智能·算法·spring·ai·动态规划
IT小白杨7 小时前
从环境制备到自动化工作流:多账号运营的工程化架构拆解
java·经验分享·自动化·安全架构·指纹浏览器
豆瓣鸡8 小时前
算法日记 - Day3
java·开发语言·算法
萧瑟余晖8 小时前
Java深入解析篇九之NIO详解
java·网络·nio
The Chosen One9858 小时前
高进度算法模板速记(待完善)
java·前端·算法
极光代码工作室11 小时前
基于SpringBoot的课程预约系统
java·springboot·web开发·后端开发
Leighteen11 小时前
`try-finally` 里的 `return`:为什么 `finally` 会悄悄改掉返回值、吞掉异常
java·开发语言
名字还没想好☜12 小时前
Go 的 time.After 在 select 循环里内存泄漏:定时器堆积原理与 timer.Reset 正确姿势
java·数据库·golang·go·goroutine