【问题标题】:How to avoid compressing of image, audio and video files downloaded from remote ssh using libssh scp command in c++?如何避免使用 C++ 中的 libssh scp 命令压缩从远程 ssh 下载的图像、音频和视频文件?
【发布时间】:2020-11-09 15:45:33
【问题描述】:

我正在尝试下载存储在远程计算机上的几个文件。这些文件可以是文本文件、图像文件(jpeg、jpg 形式)、视频或音频文件。文本文件下载成功没有问题,我也可以在我下载它们的本地机器上打开它。

但图片文件和其他视频、音频文件下载后打不开。当我检查时,它们与原始文件的大小不同。比如说原始文件是 30kb,但下载的文件只有 5kb。这就是我下载后无法在本地打开这些文件的原因?

我正在使用libsshscp 函数。以下是我正在尝试的:

#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);

    }

我该如何解决?

【问题讨论】:

  • 也许(没有投票,所以我不知道)因为您发布的代码是不是 一个minimal reproducible example,我们可以复制粘贴并测试自己。不过,我确实出于这个原因投票关闭。
  • 哦,好吧。让我按照指南提供代码。感谢您指出。欣赏。
  • 我的心理调试能力告诉我,您正在从远程系统读取不完整的文件,因为当您读取文件时,那里的某些进程仍在写入文件。
  • @Kenster 文件没有同时写入。他们实际上已经在那里了。此外,如果是这种情况,它甚至应该不完整地读取文本文件。
  • 这仍然不是一个最小的完整可验证示例。如果我猜的话,我认为您向std::fwrite() 发送了错误的参数,并且您错误地使用了返回值。

标签: c++ ssh scp libssh


【解决方案1】:
if (fwrite(buffer, rc, 1, fptr) != t_filesize)

应该是

if (fwrite(buffer, 1, rc, fptr) != rc)

或者

if (fwrite(buffer, rc, 1, fptr) != 1)

rc1 交换。你打算写rc字节,第二个参数是每个单元的大小,第三个是单元数。两者都与t_filesize 没有任何关系。


while (rc >= 0)

不足,您还需要一个计数器来记录已接收的总字节数。在循环中以rc 递增,如果total &gt;= t_filesize 则中断。


rc = ssh_scp_read(scp, buffer, sizeof(buffer));

扩展到

rc = ssh_scp_read(scp, buffer, min(sizeof(buffer), t_filesize - total));

因此您不会请求读取不可用的字节。


至于为什么你的文件太小,是因为你遇到了前面提到的错误处理。您只会使第一个缓冲区满(分别甚至没有,因为缓冲区没有完全使用),并且您已经从传输中返回。

【讨论】:

  • 非常感谢您的回答。让我验证并确认。所以关于total &gt;= t_filesize,我需要添加total = 0,然后是total = total + rc,在while循环中,它将是while(rc&gt;=0 &amp;&amp; total &gt;= t_filesize)。如果我错了,请纠正我。
  • 关于你的最后一条评论,rc = ssh_scp_read(scp, buffer, min(sizeof(buffer), t_filesize - total)); 我想应该处理一下吗?让我试着确认一下。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-01
  • 1970-01-01
  • 2016-04-26
  • 2023-01-14
相关资源
最近更新 更多