如何避免使用 C++ 中的 libssh scp 命令压缩从远程 ssh 下载的图像、音频和视频文件?
How to avoid compressing of image, audio and video files downloaded from remote ssh using libssh scp command in c++?
我正在尝试下载存储在远程计算机上的几个文件。这些文件可以是文本文件、图像文件(jpeg、jpg 格式)、视频或音频文件。文本文件下载成功,没有问题,我也可以在我下载它们的本地机器上打开它。
但是图片文件和其他视频、音频文件下载后打不开。当我检查时,它们与原始文件的大小不同。比如原始文件是 30kb,但下载的文件只有 5kb。这就是我下载后无法在本地打开这些文件的原因?
我正在使用 libssh
的 scp
功能。以下是我正在尝试的:
#include <iostream>
#include <string>
#include <libssh.h>
#include <stdlib.h>
#include <fstream>
#include <stdio.h>
#include <Windows.h>
#include <fcntl.h>
#include <sstream>
#include <io.h>
using namespace std;
static int fetch_files(ssh_session session){
int size;
//char buffer[16384];
int mode;
int rc;
//creating scp session to read from remote host for this file
ssh_scp scp = ssh_scp_new(session, SSH_SCP_READ | SSH_SCP_RECURSIVE, "/home/snaps.jpg");
//executing the init
rc = ssh_scp_init(scp);
//pulling from request object
rc = ssh_scp_pull_request(scp);
if (rc != SSH_SCP_REQUEST_NEWFILE)
{
std::cout << "Error receiving information about file: rc != SSH_SCP_REQUEST_NEWFILE";
return -3;
}
else {
//trying to download the file from the created scp object
int t_filesize = ssh_scp_request_get_size(scp);
cout << "filesize is = " << t_filesize;
string t_filename = strdup(ssh_scp_request_get_filename(scp));
cout << "File name read is = " << t_filename;
int t_filemode = ssh_scp_request_get_permissions(scp);
cout << "File mode is = " << t_filemode;
//fprintf(stderr, "Receiving file %s, size %d, permisssions 0%o\n", t_filename, t_filesize, t_filemode);
FILE *fptr = fopen("file.jpg", "w");
if (NULL == fptr)
{
fprintf(stderr, "Error opening local file: %s, error %s\n", t_filename, strerror(errno));
ssh_scp_deny_request(scp, "Unable to open local file");
}
ssh_scp_accept_request(scp);
while (rc >= 0)
{ //reading and storing into buffer to write on local file system
rc = ssh_scp_read(scp, buffer, sizeof(buffer));
cout << "Buffer = " << buffer;
//cout << "RC = " << rc << " and SSH_ERROR is = " << SSH_ERROR;
if (rc == SSH_ERROR)
{
fprintf(stderr, "Error receiving file data: %s\n", ssh_get_error(session));
fclose(fptr);
ssh_scp_close(scp);
ssh_scp_free(scp);
return rc;
}
//fprintf(stderr, "Bytes received = %d\n", rc);
if (fwrite(buffer, rc, 1, fptr) != t_filesize)
{
fprintf(stderr, "Error writing file data: %s\n", strerror(errno));
fclose(fptr);
ssh_scp_close(scp);
ssh_scp_free(scp);
return rc;
}
}
cout << "Buffer is = " << buffer;
fclose(fptr);
}
我该如何解决?
if (fwrite(buffer, rc, 1, fptr) != t_filesize)
应该是
if (fwrite(buffer, 1, rc, fptr) != rc)
或
if (fwrite(buffer, rc, 1, fptr) != 1)
rc
和 1
被交换了。您打算写入 rc
字节,第二个参数是每个单元的大小,第三个是单元数。两者都与 t_filesize
没有任何关系。
while (rc >= 0)
还不够,您还需要一个计数器来计算尚未收到的总字节数。在循环中递增 rc
并在 total >= t_filesize
.
时中断
rc = ssh_scp_read(scp, buffer, sizeof(buffer));
扩展到
rc = ssh_scp_read(scp, buffer, min(sizeof(buffer), t_filesize - total));
因此您不请求读取不可用的字节。
至于为什么你的文件太小,是因为你运行进入了前面提到的错误处理。你只会得到第一个缓冲区满的(分别甚至没有,因为缓冲区没有完全使用),并且你已经 return 来自传输。
我正在尝试下载存储在远程计算机上的几个文件。这些文件可以是文本文件、图像文件(jpeg、jpg 格式)、视频或音频文件。文本文件下载成功,没有问题,我也可以在我下载它们的本地机器上打开它。
但是图片文件和其他视频、音频文件下载后打不开。当我检查时,它们与原始文件的大小不同。比如原始文件是 30kb,但下载的文件只有 5kb。这就是我下载后无法在本地打开这些文件的原因?
我正在使用 libssh
的 scp
功能。以下是我正在尝试的:
#include <iostream>
#include <string>
#include <libssh.h>
#include <stdlib.h>
#include <fstream>
#include <stdio.h>
#include <Windows.h>
#include <fcntl.h>
#include <sstream>
#include <io.h>
using namespace std;
static int fetch_files(ssh_session session){
int size;
//char buffer[16384];
int mode;
int rc;
//creating scp session to read from remote host for this file
ssh_scp scp = ssh_scp_new(session, SSH_SCP_READ | SSH_SCP_RECURSIVE, "/home/snaps.jpg");
//executing the init
rc = ssh_scp_init(scp);
//pulling from request object
rc = ssh_scp_pull_request(scp);
if (rc != SSH_SCP_REQUEST_NEWFILE)
{
std::cout << "Error receiving information about file: rc != SSH_SCP_REQUEST_NEWFILE";
return -3;
}
else {
//trying to download the file from the created scp object
int t_filesize = ssh_scp_request_get_size(scp);
cout << "filesize is = " << t_filesize;
string t_filename = strdup(ssh_scp_request_get_filename(scp));
cout << "File name read is = " << t_filename;
int t_filemode = ssh_scp_request_get_permissions(scp);
cout << "File mode is = " << t_filemode;
//fprintf(stderr, "Receiving file %s, size %d, permisssions 0%o\n", t_filename, t_filesize, t_filemode);
FILE *fptr = fopen("file.jpg", "w");
if (NULL == fptr)
{
fprintf(stderr, "Error opening local file: %s, error %s\n", t_filename, strerror(errno));
ssh_scp_deny_request(scp, "Unable to open local file");
}
ssh_scp_accept_request(scp);
while (rc >= 0)
{ //reading and storing into buffer to write on local file system
rc = ssh_scp_read(scp, buffer, sizeof(buffer));
cout << "Buffer = " << buffer;
//cout << "RC = " << rc << " and SSH_ERROR is = " << SSH_ERROR;
if (rc == SSH_ERROR)
{
fprintf(stderr, "Error receiving file data: %s\n", ssh_get_error(session));
fclose(fptr);
ssh_scp_close(scp);
ssh_scp_free(scp);
return rc;
}
//fprintf(stderr, "Bytes received = %d\n", rc);
if (fwrite(buffer, rc, 1, fptr) != t_filesize)
{
fprintf(stderr, "Error writing file data: %s\n", strerror(errno));
fclose(fptr);
ssh_scp_close(scp);
ssh_scp_free(scp);
return rc;
}
}
cout << "Buffer is = " << buffer;
fclose(fptr);
}
我该如何解决?
if (fwrite(buffer, rc, 1, fptr) != t_filesize)
应该是
if (fwrite(buffer, 1, rc, fptr) != rc)
或
if (fwrite(buffer, rc, 1, fptr) != 1)
rc
和 1
被交换了。您打算写入 rc
字节,第二个参数是每个单元的大小,第三个是单元数。两者都与 t_filesize
没有任何关系。
while (rc >= 0)
还不够,您还需要一个计数器来计算尚未收到的总字节数。在循环中递增 rc
并在 total >= t_filesize
.
rc = ssh_scp_read(scp, buffer, sizeof(buffer));
扩展到
rc = ssh_scp_read(scp, buffer, min(sizeof(buffer), t_filesize - total));
因此您不请求读取不可用的字节。
至于为什么你的文件太小,是因为你运行进入了前面提到的错误处理。你只会得到第一个缓冲区满的(分别甚至没有,因为缓冲区没有完全使用),并且你已经 return 来自传输。