libssh slow for file operations download and upload and corrupted file on windows
I followed the documentation here https://api.libssh.org/master/libssh_tutor_sftp.html to write a small program in c to download a remote file, the program is working but downloading a 120MB file takes 12-14 seconds to complete, compared to winscp, filezila or pscp which only takes 2 seconds to complete. How to improve this speed?
PS D:\MyDartProjects\fsbackup\libssh_binding\libssh_c_wrapper\x64\Release> Measure-Command {pscp -pw Ins257257 isaque.neves@192.168.133.13:/home/isaque.neves/go1.11.4.linux-amd64.tar.gz ./go1.11.4.linux-amd64.tar.gz }
Days : 0
Hours : 0
Minutes : 0
Seconds : 2
Milliseconds : 575
Ticks : 25755922
TotalDays : 2,98100949074074E-05
TotalHours : 0,000715442277777778
TotalMinutes : 0,0429265366666667
TotalSeconds : 2,5755922
TotalMilliseconds : 2575,5922
PS D:\MyDartProjects\fsbackup\libssh_binding\libssh_c_wrapper\x64\Release> Measure-Command {./libssh_wrapper.exe}
Days : 0
Hours : 0
Minutes : 0
Seconds : 14
Milliseconds : 360
Ticks : 143600026
TotalDays : 0,000166203733796296
TotalHours : 0,00398888961111111
TotalMinutes : 0,239333376666667
TotalSeconds : 14,3600026
TotalMilliseconds : 14360,0026
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_NONSTDC_NO_DEPRECATE
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <stdexcept>
#include <string.h>
#include <exception>
#include <fstream>
#include <libssh/callbacks.h>
#include <libssh/libssh.h>
#include <libssh/sftp.h>
#include "custom_exception.cpp"
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <io.h>
#include <time.h>
#include <chrono>
using std::chrono::high_resolution_clock;
using std::chrono::duration_cast;
using std::chrono::duration;
using std::chrono::milliseconds;
//using namespace std;
using std::string;
using std::cout;
using std::endl;
using std::cin;
// Good chunk size
#define MAX_XFER_BUF_SIZE 16384
int sftpDownloadFileTo(ssh_session session, const char* fullRemotePath, const char* fullLocalPath)
{
int access_type;
sftp_file file;
char buffer[MAX_XFER_BUF_SIZE * 8];//128KB
ssize_t nbytes, nwritten, rc;
int fd;
access_type = O_RDONLY;
sftp_session sftp = sftp_new(session);
if (sftp == NULL)
{
fprintf(stderr, "Error allocating SFTP session: %s\n",
ssh_get_error(session));
return SSH_ERROR;
}
rc = sftp_init(sftp);
if (rc != SSH_OK)
{
fprintf(stderr, "Error initializing SFTP session: %d.\n",
sftp_get_error(sftp));
sftp_free(sftp);
return rc;
}
file = sftp_open(sftp, fullRemotePath, access_type, 0);
if (file == NULL) {
fprintf(stderr, "Can't open file for reading: %s\n", ssh_get_error(session));
return SSH_ERROR;
}
fd = open(fullLocalPath, O_CREAT | O_RDWR, 0777);
if (fd < 0) {
fprintf(stderr, "Can't open file for writing: %s\n",
strerror(errno));
return SSH_ERROR;
}
for (;;) {
nbytes = sftp_read(file, buffer, sizeof(buffer));
if (nbytes == 0) {
break; // EOF
}
else if (nbytes < 0) {
fprintf(stderr, "Error while reading file: %s\n",
ssh_get_error(session));
sftp_close(file);
return SSH_ERROR;
}
nwritten = write(fd, buffer, nbytes);
if (nwritten != nbytes) {
fprintf(stderr, "Error writing: %s\n",
strerror(errno));
sftp_close(file);
return SSH_ERROR;
}
}
rc = sftp_close(file);
if (rc != SSH_OK) {
fprintf(stderr, "Can't close the read file: %s\n",
ssh_get_error(session));
return rc;
}
sftp_free(sftp);
return SSH_OK;
}
int main()
{
ssh_session my_ssh_session;
int rc;
int port = 22;
string password = "Ins257257";
auto host = "192.168.133.13";
auto username = "isaque.neves";
int verbosity = SSH_LOG_PROTOCOL;
// Abra a sessão e defina as opções
my_ssh_session = ssh_new();
if (my_ssh_session == NULL)
exit(-1);
ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, host);
//ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &port);
// Conecte-se ao servidor
rc = ssh_connect(my_ssh_session);
if (rc != SSH_OK)
{
fprintf(stderr, "Error connecting to host: %s\n",
ssh_get_error(my_ssh_session));
exit(-1);
}
// Autenticar-se
rc = ssh_userauth_password(my_ssh_session, username, password.c_str());
if (rc != SSH_AUTH_SUCCESS)
{
fprintf(stderr, "Error authenticating with password: %s\n",
ssh_get_error(my_ssh_session));
ssh_disconnect(my_ssh_session);
ssh_free(my_ssh_session);
exit(-1);
}
clock_t tic = clock();
auto t1 = high_resolution_clock::now();
sftpDownloadFileTo(my_ssh_session, "/home/isaque.neves/go1.11.4.linux-amd64.tar.gz", "D:/MyDartProjects/fsbackup/libssh_binding/go1.11.4.linux-amd64.tar.gz");
auto t2 = high_resolution_clock::now();
clock_t toc = clock();
duration<double, std::milli> ms_double = t2 - t1;
std::cout << ms_double.count() << " ms\r\n";
printf("Elapsed: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC);
ssh_disconnect(my_ssh_session);
ssh_free(my_ssh_session);
std::cout << "End\n";
return 0;
}
https://github.com/insinfo/fsbackup/tree/main/libssh_binding/libssh_c_wrapper