惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Azure Blog
Microsoft Azure Blog
量子位
小众软件
小众软件
C
Cybersecurity and Infrastructure Security Agency CISA
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Tenable Blog
V
Vulnerabilities – Threatpost
Know Your Adversary
Know Your Adversary
T
Threat Research - Cisco Blogs
Latest news
Latest news
Spread Privacy
Spread Privacy
C
Cyber Attacks, Cyber Crime and Cyber Security
NISL@THU
NISL@THU
T
Tor Project blog
Hacker News: Ask HN
Hacker News: Ask HN
V2EX - 技术
V2EX - 技术
T
The Exploit Database - CXSecurity.com
博客园 - 三生石上(FineUI控件)
K
Kaspersky official blog
Cyberwarzone
Cyberwarzone
博客园 - 叶小钗
博客园 - 聂微东
Last Week in AI
Last Week in AI
爱范儿
爱范儿
腾讯CDC
博客园 - Franky
美团技术团队
J
Java Code Geeks
O
OpenAI News
L
Lohrmann on Cybersecurity
Simon Willison's Weblog
Simon Willison's Weblog
有赞技术团队
有赞技术团队
T
Threatpost
G
GRAHAM CLULEY
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
宝玉的分享
宝玉的分享
I
Intezer
N
News and Events Feed by Topic
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
The Blog of Author Tim Ferriss
S
Security @ Cisco Blogs
Forbes - Security
Forbes - Security
N
News | PayPal Newsroom
Stack Overflow Blog
Stack Overflow Blog
Scott Helme
Scott Helme
H
Hacker News: Front Page
Cloudbric
Cloudbric

风萧古道 - 勤学苦练,年复一年

游戏服务器开发经验(五)应对复杂需求 沉浸式体验东汉末年生活 - 《真三国无双 起源》玩后感 怒其不争!致2025年HLTV的Top18-NiKo Linux家用服务器维护指南 游戏服务器开发经验(四)避免写Bug的习惯、技巧和心态 游戏服务器开发经验(三)线上维护 游戏服务器开发经验(二)避免内存泄露 游戏服务器开发经验(一)道具防刷 35岁找不到工作,绝对不会是软件开发人员的结局 用爱发电项目开发两个月的心得体会 以魏延“子午谷奇谋”讨论软件需求可行性问题 MQTT协议中可变长度的具体计算方式(有计算过程解析) 关于游戏服务器配置表功能的探讨 Java并发编程中上锁的几种方式 如何用C++分割一个字符串? CSAPP第二章-信息的表示与处理 我的自我介绍 Windows XP虚拟机中文版无需激活下载 Java TreeSet的一些用法和特性 Linux C++ Socket实战 传统软件服务器与游戏服务器架构区别 独立个人项目开发心得 - 任务切分、挑战性、实用性和半途而废 使用Python实现简单UDP Ping 使用Python开发一个简单的web服务器 Kotlin手动实现一个最简单的哈希表 Kotlin实现二叉堆、大顶堆、优先级队列 搭建Spark实战环境(3台linux虚拟机集群)(一)样板机的搭建 Springboot操作MongoDB,包括增改查及复杂操作 Unison在Linux下的安装与使用 一个被废弃的项目——自动爬取信息然后发给我自己邮箱上 Python连接MongoDB和Oracle实战 MongoDB常用查询语句 vue和springboot项目部署到Linux服务器 Python的一些用法(可能不定时更新) java正则表达式 - 双反斜杠(\)和Pattern的matches()与find() 简述爬虫对两种网站的不同爬取方式 Vue的路由配置及手动改地址栏为啥又跳转回来?? [JavaScript]JS基础知识 [Mybatis]逆向工程中Select语句查询不出‘TEXT’字段 [编译原理]FIRST、FOLLOW和SELECT [Spring]Spring学习笔记 [算法]分布估计算法 - 一种求解多维背包问题的混合分布估计算法_王凌 [日常]我做独立博客的原因 人间值得 深入理解计算机系统 想想就开心! 最重要的事,只有一件 藏书 被讨厌的勇气 关于 简历 朋友 尊重自己:给予与接收的心灵艺术
Java实现类似WINSCP访问远程Linux服务器,执行命令、上传文件、下载文件
JonathanLin · 2020-02-20 · via 风萧古道 - 勤学苦练,年复一年

pom.xml添加的依赖:

<!-- https://mvnrepository.com/artifact/ch.ethz.ganymed/ganymed-ssh2 --> 
<dependency> 
    <groupId>ch.ethz.ganymed</groupId> 
    <artifactId>ganymed-ssh2</artifactId> 
    <version>262</version> 
</dependency>

这里注意,不同版本的这玩意用法有差别。这里我使用的是262。

操作类代码如下:

import ch.ethz.ssh2.*;

import java.io.*;

/**
 * @Author: 风萧古道的博客 windypath.com
 * @Date: 2019/11/29 15:14
 */
public class SSHUtil {

    // uploadFile to Linux

    /**
     * 上传文件到Linux
     * 
     * @param ip ip地址
     * @param username 登录用户名
     * @param password 密码
     * @param remoteFilePath 目标文件所在完整目录
     * @param file 本地文件File对象
     * @return
     */
    public static boolean uploadFile(String ip, String username, String password, String remoteFilePath, File file) {

        FileInputStream input = null;
        BufferedOutputStream boutput = null;
        Connection conn = null;
        try {

            conn = new Connection(ip);
            conn.connect();
            boolean isAuthenticated = conn.authenticateWithPassword(username, password);
            if (isAuthenticated == false) {
                throw new IOException("Authentication failed.");
            }
            SCPClient scpClient = conn.createSCPClient();
            boutput = scpClient.put(file.getName(), file.length(), remoteFilePath, "0600");
            byte[] buffer = new byte[1024 * 8];
            input = new FileInputStream(file);


            int length = -1;
            while ((length = input.read(buffer)) != -1) {
                boutput.write(buffer, 0, length);
            }
            boutput.flush();

        } catch (IOException e) {
            e.printStackTrace(System.err);
        } finally {
            try {

                boutput.close();
                input.close();
                conn.close();
            } catch (IOException e) {
                e.printStackTrace(System.err);
            }
        }
        return true;
    }


  
    /**
     * 从远程服务器上下载文件
     *
     * @param ip ip地址
     * @param username 用户名
     * @param password 密码
     * @param remoteFile 要下载的文件的完整路径
     * @param localFileName 下载到本地的文件名
     * @return
     */
    public static boolean downloadFile(String ip, String username, String password, String remoteFile, String localFileName) {
        SCPInputStream binput = null;
        FileOutputStream output = null;
        BufferedOutputStream boutput = null;
        Connection conn = null;
        try {
            File file = new File(localFileName);
            conn = new Connection(ip);
            conn.connect();
            boolean isAuthenticated = conn.authenticateWithPassword(username, password);
            if (isAuthenticated == false) {
                throw new IOException("Authentication failed.");
            }
            SCPClient scpClient = conn.createSCPClient();
            binput = scpClient.get(remoteFile);
            output = new FileOutputStream(file);
            boutput = new BufferedOutputStream(output);
            byte[] buffer = new byte[1024 * 8];
            int length = -1;
            while ((length = binput.read(buffer)) != -1) {
                boutput.write(buffer, 0, length);
            }


        } catch (IOException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                binput.close();
                boutput.close();
                output.close();
                conn.close();
            } catch (IOException e) {
                e.printStackTrace(System.err);
            }
        }
        return true;
    }

    /**
     * 获取远程文件的输入流
     *
     * @param ip ip
     * @param username 用户名
     * @param password 密码
     * @param remoteFile 远程文件的完整地址
     * @return 输入流
     */
    public static SCPInputStream getRemoteFileInputStream(String ip, String username, String password, String remoteFile) {
        SCPInputStream binput = null;

        Connection conn = null;
        try {

            conn = new Connection(ip);
            conn.connect();
            boolean isAuthenticated = conn.authenticateWithPassword(username, password);
            if (isAuthenticated == false) {
                throw new IOException("Authentication failed.");
            }
            SCPClient scpClient = conn.createSCPClient();
            binput = scpClient.get(remoteFile);

        } catch (IOException e) {
            e.printStackTrace(System.err);
        }
        return binput;
    }

    /**
     * 执行远程服务器的控制台命令
     *
     * @param ip ip地址
     * @param username 用户名
     * @param password 密码
     * @param cmd 控制台命令
     */
    public static void executeCmd(String ip, String username, String password, String cmd) {
        Connection conn = null;
        try {

            conn = new Connection(ip);
            conn.connect();
            boolean isAuthenticated = conn.authenticateWithPassword(username, password);
            if (isAuthenticated == false) {
                throw new IOException("Authentication failed.");
            }
            Session sess = conn.openSession();
            sess.execCommand(cmd + "\n");
            InputStream stdout = new StreamGobbler(sess.getStdout());
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(stdout));
            while (true) {
                String line = br.readLine();
                if (line == null) {
                    break;
                }
                System.out.println(line);
            }


        } catch (IOException e) {
            e.printStackTrace(System.err);
        } finally {

            conn.close();

        }
    }

}

值得一提的是,uploadFile()方法的最后一个参数传入的是指向本地文件的一个File,也就是要上传的文件,而在downloadFile()方法中,最后一个参数是字符串,就是将目标文件下载下来之后,要叫什么名字,记得带上后缀。

执行命令的话,执行一次就新开一次session。一个session(好像貌似)不能做两件事(如上传文件的过程中创建一个新文件夹,再以新文件夹的目录为目标上传目录)。