Как избежать сжатия изображений, аудио и видео файлов, загруженных с удаленного ssh с помощью команды libssh scp в c ++? - PullRequest
0 голосов
/ 25 февраля 2019

Я пытаюсь загрузить несколько файлов, хранящихся на удаленной машине.Это могут быть текстовые файлы, файлы изображений (в формате jpeg, jpg), видео или аудио файлы.Текстовые файлы успешно загружаются без проблем, и я также могу открыть их на своем локальном компьютере, где я их загружаю.Но файлы изображений и другие видео, аудио файлы не открываются после загрузки.Когда я проверил, они не были размером с оригинальный файл.Как, скажем, исходный файл был размером 30 КБ, но загруженный файл был только 5 КБ.И это причина того, что, возможно, я не могу открыть эти файлы локально после загрузки?Я использую scp функцию libssh.Вот то, что я пытаюсь сделать:

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

    }

Пожалуйста, дайте мне знать, как я могу это решить.Кроме того, пожалуйста, дайте мне знать, если вам нужны какие-либо дополнительные детали для того же.

1 Ответ

0 голосов
/ 28 февраля 2019
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));

Таким образом, вы не запрашиваете чтение байтов, которые не являютсядоступны.


Что касается того, почему ваши файлы слишком малы, это потому, что вы столкнулись с ошибочной обработкой ошибок, упомянутой первой.Вы получаете только первый заполненный буфер (соответственно, даже не тот, потому что буфер используется не полностью), и вы уже вернетесь из передачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...