mina-sshd icon indicating copy to clipboard operation
mina-sshd copied to clipboard

sftp clients based on the Mina-sshd and JSCH components upload and download files at very different speeds

Open czldb2 opened this issue 7 months ago • 4 comments

Phenomenon:

Uploading and downloading files with mina-sshd is about twice as slow as JSCH 企业微信截图_17198149038657

Code:

Mina-sshd

Dependency
<dependency>
    <groupId>org.apache.sshd</groupId>
    <artifactId>sshd-core</artifactId>
    <version>2.13.0</version>
</dependency>
<dependency>
    <groupId>org.apache.sshd</groupId>
    <artifactId>sshd-common</artifactId>
    <version>2.13.0</version>
</dependency>
<dependency>
    <groupId>org.apache.sshd</groupId>
    <artifactId>sshd-sftp</artifactId>
    <version>2.13.0</version>
</dependency>
demo
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.future.ConnectFuture;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.sftp.client.SftpClient;
import org.apache.sshd.sftp.client.SftpClientFactory;
import org.apache.sshd.common.util.io.IoUtils;

import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;

public class SftpTestTool {

    public static void main(String[] args) {
        String host = "x.x.x.x";
        int port = 22;
        String user = "root";
        String password = "root123";

        String localFile = "src/main/resources/temp/temp.gz";
        String remoteFile = "/home/user/temp/temp.gz";

        SshClient client = SshClient.setUpDefaultClient();
        client.start();

        long connectStartTime = System.currentTimeMillis();
        try (ClientSession session = createSession(client, host, port, user, password)) {
            SftpClientFactory factory = SftpClientFactory.instance();
            try (SftpClient sftpClient = factory.createSftpClient(session)) {
                long connectEndTime = System.currentTimeMillis();
                System.out.println("Mina SSHD connect Time: " + (connectEndTime - connectStartTime) + " ms");
                long uploadStartTime = System.currentTimeMillis();
                try (InputStream localInputStream = Files.newInputStream(Paths.get(localFile));
                     OutputStream remoteOutputStream = sftpClient.write(remoteFile)) {
                    IoUtils.copy(localInputStream, remoteOutputStream);
                }
                long uploadEndTime = System.currentTimeMillis();
                System.out.println("Mina SSHD Upload Time: " + (uploadEndTime - uploadStartTime) + " ms");

                long downloadStartTime = System.currentTimeMillis();
                try (InputStream remoteInputStream = sftpClient.read(remoteFile);
                     OutputStream localOutputStream = Files.newOutputStream(Paths.get("src/main/resources/temp/temp.gz.bak"))) {
                    IoUtils.copy(remoteInputStream, localOutputStream);
                }
                long downloadEndTime = System.currentTimeMillis();
                System.out.println("Mina SSHD Download Time: " + (downloadEndTime - downloadStartTime) + " ms");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client.stop();
        }
    }

    private static ClientSession createSession(SshClient client, String host, int port, String user, String password) throws Exception {
        ConnectFuture connectFuture = client.connect(user, host, port);
        connectFuture.await(5, TimeUnit.SECONDS);

        ClientSession session = connectFuture.getSession();
        session.addPasswordIdentity(password);
        session.auth().verify(5, TimeUnit.SECONDS);
        return session;
    }

}

JSCH

Dependency
<dependency>
    <groupId>com.github.mwiede</groupId>
    <artifactId>jsch</artifactId>
    <version>0.2.3</version>
</dependency>
demo
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;

public class JSCHTestTool {

public static void main(String[] args) {
String host = "x.x.x.x";
 int port = 22;
 String user = "root";
 String password = "root123";

 String localFile = "src/main/resources/temp/temp.gz";
 String remoteFile = "/home/user/temp/temp.gz";

 JSch jsch = new JSch();
 Session session = null;
 ChannelSftp channelSftp = null;

 try {
long connectStartTime = System.currentTimeMillis();
 session = jsch.getSession(user, host, port);
 session.setPassword(password);
 Properties config = new Properties();
 config.put("StrictHostKeyChecking", "no");
 session.setConfig(config);
 session.connect();

 channelSftp = (ChannelSftp) session.openChannel("sftp");
 channelSftp.connect();
 long connectEndTime = System.currentTimeMillis();
 System.out.println("JSch connect Time: " + (connectEndTime - connectStartTime) + " ms");

 long uploadStartTime = System.currentTimeMillis();
 channelSftp.put(new FileInputStream(localFile), remoteFile);
 long uploadEndTime = System.currentTimeMillis();
 System.out.println("JSch Upload Time: " + (uploadEndTime - uploadStartTime) + " ms");

 long downloadStartTime = System.currentTimeMillis();
 channelSftp.get(remoteFile, new FileOutputStream("src/main/resources/temp/temp.gz.bak"));
 long downloadEndTime = System.currentTimeMillis();
 System.out.println("JSch Download Time: " + (downloadEndTime - downloadStartTime) + " ms");

 } catch (Exception e) {
e.printStackTrace();
 } finally {
if (channelSftp != null) {
channelSftp.disconnect();
 }
if (session != null) {
session.disconnect();
 }
}
}

}

Question

Is there something wrong with my coding? Is there any configuration or correct encoding of mina-sshd so that my sftp function can reach the same speed level as jsch?

czldb2 avatar Jul 01 '24 06:07 czldb2