如何使用 C 以编程方式 SCP 文件?

发布于 2024-07-04 21:47:47 字数 339 浏览 10 评论 0原文

在 Unix 环境中使用 C 进行 scpsftp 复制的最佳方法是什么?

我有兴趣了解最好使用的库以及一个示例(如果可能的话)。 我正在 Solaris 服务器上工作,Sun 工具已安装。

What would be the best way to do an scp or sftp copy in a Unix environment using C?

I'm interested in knowing the best library to use and an example if at all possible. I'm working on a Solaris server with the Sun tools installed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

伴我老 2024-07-11 21:47:47

过去,我只是简单地调用包含文件传输代码的 shell 脚本。

int transferFile()
{
  // Declare the transfer command
  char transferCommand[50] = "/home/tyler/transferFile.shl";
  // Execute the command
  return system(transferCommand);
}

如果传输命令成功返回,则返回 1。

In the past, I've simply called a shell script that contained the file transfer code.

int transferFile()
{
  // Declare the transfer command
  char transferCommand[50] = "/home/tyler/transferFile.shl";
  // Execute the command
  return system(transferCommand);
}

This will return 1 if the transfer command returns successfully.

不即不离 2024-07-11 21:47:47

我并不是真正的 C 专家,但我认为您可以使用 system() 来运行操作系统命令。 这假设您实际上不想重新实现 scp,只是使用它。

I'm not really a C expert, but I think you can use system() to run OS commands. This would assume that you don't actually want to re-implement scp, just use it.

一片旧的回忆 2024-07-11 21:47:47

我一直只使用 system() 命令。 当然,执行此操作需要您在客户端和目标计算机之间正确安装 SSH 密钥,这样就不会提示输入密码。

I've always just used the system() command. Of course doing this requires that you have SSH keys properly installed between the client and target machine so that it doesn't prompt for the password.

天冷不及心凉 2024-07-11 21:47:47

您可以使用 libssh 进行 sftp。 我在这里为您放置了一些具有暂停/恢复功能并可在 Windows 上运行的代码。 对于Linux,您需要替换本地文件处理函数。 我无法复制整个课程,因为它将超出此网站的限制。 将用户名、密码和主机名更改为 SFTP 服务器的正确等效项:

int main(array<System::String ^> ^args)
{
    //Console::WriteLine(L"Hello World");

    pSFTPConnector  sshc = new  SFTPConnector(L".\\", L"127.0.0.1", 22, L"iman", L"iman");  // Change the hostname, port, username, password to your SFTP server, your credentials

    //FILE *nullfile = fopen("null", "w");
    //sshc->setLogFile(nullfile);
    sshc->setVerbosity(SSH_LOG_RARE);        // You can change the verbosity as appropriate for you

    int i = sshc->InitSession();
    i = sshc->ConnectSession();
    i = sshc->InitSFTP();

    //i = sshc->SFTPrename("renamed_myfile.txt", "myfile.txt");  // Change these file names
    //i = sshc->Makedir("sftpdir");
    //i = sshc->testUploadFile("myfile2.txt", "1234567890testfile");

    // Change these file names to whatever appropriate
    //i = sshc->SFTPget("c:\\testdir\\Got_CAR_HIRE_FINAL_test.jpg", "CAR_HIRE_FINAL_test.jpg", 64*1024);
    i = sshc->SFTPget("c:\\testdir\\get_downloaded_CAR_HIRE_FINAL.jpg", "CAR_HIRE_FINAL.jpg", 64 *1024);
    i = sshc->SFTPreget("c:\\testdir\\reget_downloaded_CAR_HIRE_FINAL.jpg", "CAR_HIRE_FINAL.jpg", 64 * 1024);
    i = sshc->SFTPput("c:\\testdir\\CAR_HIRE_FINAL.jpg", "put_CAR_HIRE_FINAL.jpg", 64 * 1024);
    i = sshc->SFTPreput("c:\\testdir\\CAR_HIRE_FINAL.jpg", "reput_CAR_HIRE_FINAL.jpg", 64 * 1024);

    delete sshc;
    return 0;
}

typedef enum sshconerr {
    E_OK = 1, E_SESSION_ALOC = -1, E_SSH_CONNECT_ERR = -2, E_SFTP_ALLOC = -3, E_INIT_SFTP = -4, E_CREATE_DIR = -5, E_FILEOPEN_WRITE = -6, E_WRITE_ERR = -7,
    E_FILE_CLOSE = -8, E_FILE_OPEN_READ = -9, E_INVALID_PARAMS = -10, E_SFTP_ERR = -11, E_SFTP_READ_ERR = -12, E_SFTP_READBYTES_ERR = -13, E_GET_FILEINF = -14,
    E_LOCAL_FILE_NOTFOUND = -15, E_RENAME_ERR = -16, E_MEM_ALLOC = -17, E_LOCAL_FILE_READ = -18, E_LOCAL_FILE_RDWR = -19, E_REMOTEFILE_SEEK = -20,
    E_REMOTE_FILE_OPEN = -21, E_DELETE_ERR = -22, E_RENAME_LOCAL_FILE = -23, E_LOCAL_DELETE_FILE = -24, E_FILEOPEN_RDONLY = -25, E_SFTP_READ_EOF = -26,
    E_UNKNOWN = -999
} ESSHERR;


// Status of transfers;
typedef enum sftpstat{ES_DONE=0, ES_INPROGRESS, ES_FAILED, ES_STARTING, ES_PAUSED, ES_RESUMING, ES_CANCELLED,  ES_NONE  } ESFTPSTAT;

using namespace std;


// Statistics about the transfer;
typedef struct transferstatstruct {
    string remote_file_name;
    string local_file_name;
    __int64 total_size;
    __int64 transferred;
    __int64 averagebps;
    long long seconds_elapsed;
    long long seconds_remained;
    int percent;
    ESFTPSTAT transferstate;
} TTransStat;


#define E_SESSION_NEW -1

// These libraries are required
#pragma comment(lib, "ssh.lib")

// This is the main class that does the majority of the work

typedef class CSFTPConnector {

    private:
    ssh_session  session;             // SSH session
    sftp_session sftp;                // SFTP session
    sftp_file file;                   // Structure for a remote file
    FILE *localfile;                  // Not used on Windows, but it could be local file pointer in Unix
    FILE *logfile;                    // The file for writing logs, default is set to stderr
    string filename;                  // File name of the transfer;
    string localfilename;             // File name of local file;
    string tempfilename;              // A temporary file name will be used during the transfer which is renamed when transfer is completed.
    ESFTPSTAT transferstatus;         // State of the transfer which has one of the above values (ESFTPSTAT)
    time_t transferstarttime;         // Time of start of the transfer
    wchar_t username[SHORT_BUFF_LEN];
    wchar_t password[SHORT_BUFF_LEN];
    wchar_t hostname[SHORT_BUFF_LEN]; // Hostname of the SFTP server
    wchar_t basedir[SHORT_BUFF_LEN];  // This base directory is the directory of the public and private key structure (NOT USED IN THIS VERSION)
    int port;                         // Port of the server;
    int verbosity;                    // Degree of verbosity of libssh
    __int64  filesize;                // Total number of bytes to be transferred;
    DWORD  local_file_size_hiDWORD;   // Bill Gates cannot accept the file size
                                      // without twisting the programmers, so
                                      // he accepts them in two separate words
                                      // like this
    DWORD  local_file_size_lowDWORD;  // These two DWORDs when connected together comprise a 64 bit file size.
    __int64 lfilesize;                // Local file size
    __int64 rfilesize;                // Remote file size
    __int64 transferred;              // Number of bytes already transferred
    bool pause;                       // Pause flag
    TTransStat stats;                 // Statistics of the transfer
    HANDLE    localfilehandle;        // Windows uses handles to manipulate files. this is the handle to local file.

    ESSHERR CSFTPConnector::rwopen_existing_SFTPfile(char *fn);       // Open a file on remote (server) read/write for upload
    ESSHERR CSFTPConnector::rdopen_existing_SFTPfile(char *fn);       // Open a file on remote (server) read only for download
    ESSHERR createSFTPfile(char *fn);                                 // Create a file on server;
    ESSHERR writeSFTPfile(char *block, size_t blocksize);             // Write a block of data to the  open remote file
    ESSHERR readSFTPfile(char *block, size_t len, size_t *bytesread); // Read a block of data from the  open remote file
    ESSHERR readSFTPfile(char *block, __int64 len, DWORD *bytesread);
    ESSHERR closeSFTPfile();         // Closes the remote file;
    ESSHERR openSFTPfile(char *fn);  // Opens the remote file
    ESSHERR getSFTPfileinfo();       // Gets information about the remote file

    public:
    wstring errstring;        // The string describing last error
    ESSHERR Err;              // Error code of last error
    CSFTPConnector();         // Default constructor;
    CSFTPConnector(wchar_t *dir, wchar_t *hn, int hostport, wchar_t *un, wchar_t *pass);  // Constructor
    void setVerbosity(int v);
    int  getVerbosity();
    ESSHERR InitSession();    // Must be called before doing any transfer
    ESSHERR ConnectSession(); // Connects to the SSH server
    ESSHERR InitSFTP();       // Must be called before doing any transfer
    ESSHERR Makedir(char *newdir);
    ESSHERR testUploadFile(char *fn, char *block);             // Do not use this, only for test purposes for myself
    ESSHERR SFTPput(char *lfn, char *rfn, size_t blocksize);   // Upload a file from start
    ESSHERR SFTPreput(char *lfn, char *rfn, size_t blocksize); // Checks for previouse interrupted transfer, then
                                                               // either continues the previous transfer (if
                                                               // there was any) or starts a new one (UPLOAD)
    ESSHERR SFTPrename(char *newname, char *oldname);          // Renames a remote file( must be closed)
    ESSHERR CSFTPConnector::SFTPdelete(char *remfile);         // Deletes a remote file
    TTransStat getStatus();                                    // Gets statistics of the transfer
    ESSHERR CSFTPConnector::SFTPget(char *lfn, char *rfn, size_t blocksize);    // Downloads a file from the SFTP server
    ESSHERR CSFTPConnector::SFTPreget(char *lfn, char *rfn, size_t blocksize);  // Checks for a previous interrupted transfer,
                                                                                // then either continues the previous transfer
                                                                                // (if there was any) or starts a new one (DOWNLOAD).
    void CancelTransfer();
    void PauseTransfer();
    void setLogFile(FILE *logf); // Sets the log file. If not set, standard
                                 // error will be used. By default.
    void CloseLocalFile();
    void CloseRemoteFile();

    ~CSFTPConnector();
} SFTPConnector, *pSFTPConnector;

void CSFTPConnector::CloseLocalFile()
{
    CloseHandle(localfilehandle);
}


void CSFTPConnector::CloseRemoteFile()
{
    sftp_close(file);
}

void CSFTPConnector::setLogFile(FILE *logf)
{
    logfile = logf;
}

void CSFTPConnector::CancelTransfer()
{
    transferstatus = ES_CANCELLED;
}

void CSFTPConnector::PauseTransfer()
{
    transferstatus = ES_PAUSED;
    pause = true;
}

//----------------------------------------

ESSHERR CSFTPConnector::SFTPget(char *lfn, char *rfn, size_t blocksize)
{
    DWORD result;
    int rc;
    BOOL bresult;
    DWORD bytesread;
    filesize = 0;
    transferred = 0;

    pause = false;
    transferstatus = ES_NONE;
    char *block;
    struct stat st;
    wchar_t temp[SHORT_BUFF_LEN];
    size_t tempsize;
    wstring wlfn;
    int loopcounter = 0;

    localfilename = lfn;

    filename = rfn;

    tempfilename = string(lfn) + ".sftp_temp";
    mbstowcs_s(&tempsize, temp, tempfilename.c_str(), SHORT_BUFF_LEN);

    localfilehandle = CreateFile(temp, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (localfilehandle == INVALID_HANDLE_VALUE)
    {
        transferstatus = ES_FAILED;
        errstring = L"Could not open local file:" + wstring(temp) + L" for read and write";
        Err = E_LOCAL_FILE_RDWR;
        return E_LOCAL_FILE_RDWR;
    }

    lfilesize = 0;
    transferred = 0;

    block = (char*)malloc(blocksize + 1);
    if (block == NULL) {
        Err = E_MEM_ALLOC;
        transferstatus = ES_FAILED;
        errstring = L"Could not allocate memory for file block size";
        CloseLocalFile();
        return E_MEM_ALLOC;
    }

    result = rdopen_existing_SFTPfile((char *)rfn);

    if (result == E_OK) {
        getSFTPfileinfo();
        filesize = rfilesize;
    }
    else
    {
        Err = E_REMOTE_FILE_OPEN;
        transferstatus = ES_FAILED;
        errstring = L"Could not open remote file";
        CloseLocalFile();
        delete block;
        return E_REMOTEFILE_SEEK;
    }

    transferstatus = ES_STARTING;

    sftp_file_set_blocking(file);
    transferstarttime = time(NULL);
    transferstatus = ES_INPROGRESS;

    while (transferstatus != ES_FAILED &&
           transferstatus != ES_PAUSED &&
           transferstatus != ES_CANCELLED &&
           transferstatus != ES_DONE)
    {
        loopcounter++;

        result = readSFTPfile(block, blocksize, (size_t *)&bytesread);
        if (result != E_OK && result!= E_SFTP_READ_EOF)
        {
            errstring = L"Error reading from remote SFTP server file.";
            Err = (ESSHERR)result;
            transferstatus = ES_FAILED;
            CloseRemoteFile();
            CloseLocalFile();
            delete block;
            return (ESSHERR)result;
        }
        if (result == E_SFTP_READ_EOF)
            transferstatus = ES_DONE;
        fprintf(logfile, "Read %d bytes from input file. Number of packets: %d, %llu from %llu bytes\n", bytesread, loopcounter, transferred, filesize);

        bresult = WriteFile(localfilehandle, (LPVOID)block, bytesread, &bytesread, NULL);
        if (bytesread < blocksize)
        {
            if (bresult == FALSE)
            {
                errstring = L"Error writing to local file.";
                Err = E_LOCAL_FILE_RDWR;
                transferstatus = ES_FAILED;
                CloseRemoteFile();
                CloseLocalFile();
                delete block;
                return E_LOCAL_FILE_RDWR;
            }
            else if (bytesread == 0)
            {
                errstring = L"Transfer done.";
                Err = E_OK;
                transferstatus = ES_DONE;
                continue;
            }
        }

        Err = E_OK;

        if (pause == true)
            transferstatus = ES_PAUSED;
        if (bresult == TRUE &&  bytesread == 0)
        {
            // At the end of the file
            transferstatus = ES_DONE;
        }
        Sleep(BLOCKTRANSDELAY);
        if (loopcounter % 331 == 0)
            Sleep(77 * BLOCKTRANSDELAY);
        if (loopcounter % 3331 == 0)
            Sleep(777 * BLOCKTRANSDELAY);
    }

    // Closing files
    result = closeSFTPfile();
    CloseHandle(localfilehandle);

    Sleep(1000);

    if (transferstatus == ES_DONE)
    {
        wchar_t temp2[SHORT_BUFF_LEN];
        mbstowcs_s(&tempsize, temp2, lfn, SHORT_BUFF_LEN);
        bresult = MoveFile(temp, temp2);
        if (bresult != TRUE)
        {
            Err = E_RENAME_LOCAL_FILE;
            errstring = L"Could not rename local file: " + wstring(temp);
            transferstatus = ES_FAILED;
            delete block;
            return E_RENAME_LOCAL_FILE;
        }
    }

    if (transferstatus == ES_CANCELLED)
    {
        wchar_t temp2[SHORT_BUFF_LEN];
        mbstowcs_s(&tempsize, temp2, lfn, SHORT_BUFF_LEN);
        bresult = DeleteFile(temp);
        if (bresult != TRUE)
        {
            Err = E_LOCAL_DELETE_FILE;
            errstring = L"Could not rename local file: " + wstring(temp);
            transferstatus = ES_FAILED;
            delete block;
            return E_LOCAL_DELETE_FILE;
        }
    }
    delete block;
    return (ESSHERR) result;
}

TTransStat CSFTPConnector::getStatus()
{
    stats.seconds_elapsed = time(NULL) - transferstarttime;
    stats.averagebps = (transferred * 8) / stats.seconds_elapsed;
    if (filesize > 0) {
        stats.percent = (transferred *100)/ filesize;
        stats.seconds_remained = ((filesize - transferred) * 8) / stats.averagebps;
    }
    else
    {
        stats.percent = -1;
        stats.seconds_remained = -1;
    }
    stats.total_size = filesize;
    stats.transferstate = transferstatus;
    stats.remote_file_name = filename;
    stats.local_file_name = localfilename;

    return stats;
}

ESSHERR CSFTPConnector::SFTPrename(char *newname, char *oldname)
{
    int rc = sftp_rename(sftp, oldname, newname);
    if (rc != SSH_OK) {
        return E_RENAME_ERR;
    }

    return E_OK;
}


ESSHERR CSFTPConnector::SFTPdelete(char *remfile)
{
    int rc = sftp_unlink(sftp, remfile);
    if (rc != SSH_OK) {
        return E_DELETE_ERR;
    }
    return E_OK;
}


ESSHERR CSFTPConnector::SFTPreput(char *lfn, char *rfn, size_t blocksize)
{
    ESSHERR result;
    BOOL  bresult;
    DWORD bytesread;
    filesize = 0;
    transferred = 0;

    pause = false;
    transferstatus = ES_NONE;
    char *block;
    struct stat st;
    wchar_t temp[SHORT_BUFF_LEN];
    size_t tempsize;
    wstring wlfn;
    int loopcounter = 0;

    localfilename = lfn;
    //wlfn = wstring(lfn);
    //localfile = fopen(lfn, L"r");
    filename = rfn;
    mbstowcs_s(&tempsize, temp, lfn, SHORT_BUFF_LEN);

    //filesize = getFileSize(localfilename);

    /*if (filesize < 0) {
        transferstatus = ES_FAILED;
        Err = E_LOCAL_FILE_NOTFOUND;
        return E_LOCAL_FILE_NOTFOUND;
    }*/

    localfilehandle = CreateFile(temp, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (localfilehandle == INVALID_HANDLE_VALUE)
    {
        transferstatus = ES_FAILED;
        Err = E_LOCAL_FILE_NOTFOUND;
        return E_LOCAL_FILE_NOTFOUND;
    }
    local_file_size_lowDWORD = GetFileSize(localfilehandle, &local_file_size_hiDWORD);
    filesize = (local_file_size_hiDWORD * 0x100000000) + local_file_size_lowDWORD;

    if (filesize < 0) {
        transferstatus = ES_FAILED;
        Err = E_LOCAL_FILE_NOTFOUND;
        CloseLocalFile();
        return E_LOCAL_FILE_NOTFOUND;
    }

    block = (char*)malloc(blocksize + 1);
    if (block == NULL) {
        Err = E_MEM_ALLOC;
        transferstatus = ES_FAILED;
        errstring = L"Could not allocate memory for file block size";
        CloseLocalFile();
        return E_MEM_ALLOC;
    }

    tempfilename = string(rfn) + ".sftp_temp";

    result = rwopen_existing_SFTPfile((char *)tempfilename.c_str());
    if (result == E_OK) {
        getSFTPfileinfo();
        sftp_seek64(file, rfilesize);
        __int64 tempi64 = rfilesize & 0x00000000FFFFFFFF;
        DWORD dwlow = tempi64;
        tempi64 = (rfilesize & 0x7FFFFFFF00000000);
        tempi64 = tempi64 >> 32;
        long  dwhi = tempi64;
        DWORD dwResult = SetFilePointer(localfilehandle, dwlow, &dwhi, FILE_BEGIN);
        if (dwResult == INVALID_SET_FILE_POINTER)
        {
            transferstatus = ES_FAILED; Err = result;  return result;
        }
        transferstatus = ES_RESUMING;
        transferred = rfilesize;
    }
    else{
        result = createSFTPfile((char *)tempfilename.c_str());
        transferstatus = ES_STARTING;
        if (result != E_OK) {
            transferstatus = ES_FAILED;
            Err = result;
            CloseLocalFile();
            return result;
        }
    }
    sftp_file_set_blocking(file);
    transferstarttime = time(NULL);
    transferstatus = ES_INPROGRESS;

    while (transferstatus != ES_FAILED &&
           transferstatus != ES_PAUSED &&
           transferstatus != ES_DONE)
    {
        loopcounter++;
        bresult = ReadFile(localfilehandle, (LPVOID)block, blocksize, &bytesread, NULL);
        fprintf(logfile, "Read %d bytes from input file. Number of packets: %d, %llu from %llu bytes\n", bytesread, loopcounter, transferred, filesize);
        if (bytesread < blocksize)
        {
            if (bresult == FALSE)
            {
                errstring = L"Error reading from local file.";
                Err = E_LOCAL_FILE_READ;
                transferstatus = ES_FAILED;
                CloseRemoteFile();
                CloseLocalFile();
                return E_LOCAL_FILE_READ;
            }
            else if (bytesread == 0)
            {
                errstring = L"Transfer done.";
                Err = E_OK;
                transferstatus = ES_DONE;
                continue;
            }
        }

        result = writeSFTPfile(block, bytesread);
        if (result != E_OK && bytesread>0)
        {
            errstring = L"Error transmitting to remote SFTP server file.";
            Err = result;
            transferstatus = ES_FAILED;
            CloseRemoteFile();
            CloseLocalFile();
            return result;
        }

        Err = E_OK;
        //transferred = transferred + bytesread;
        if (pause == true)
            transferstatus = ES_PAUSED;
        if (bresult == TRUE &&  bytesread == 0)
        {
            // At the end of the file
            transferstatus = ES_DONE;
        }
        Sleep(BLOCKTRANSDELAY);
        if (loopcounter % 331 == 0)
            Sleep(77 * BLOCKTRANSDELAY);
        if (loopcounter % 3331 == 0)
            Sleep(777 * BLOCKTRANSDELAY);
    }

    CloseRemoteFile();
    CloseLocalFile();
    Sleep(1000);

    if (transferstatus == ES_CANCELLED)
    {
        result = SFTPdelete((char *)tempfilename.c_str());
        if (bresult != E_OK)
        {
            Err = E_DELETE_ERR;
            errstring = L"Could not delete remote file.";
            transferstatus = ES_FAILED;
            return E_DELETE_ERR;
        }
    }
    if (transferstatus == ES_DONE)
        result = SFTPrename(rfn, (char *)tempfilename.c_str());
    delete block;
    return result;
}


ESSHERR CSFTPConnector::getSFTPfileinfo()
{
    sftp_attributes fileinf = sftp_fstat(file);

    if (fileinf == NULL) {
        return E_GET_FILEINF;
    }

    rfilesize = fileinf->size;

    sftp_attributes_free(fileinf);
    return E_OK;
}

ESSHERR CSFTPConnector::closeSFTPfile()
{
    int rc = sftp_close(file);
    if (rc != SSH_OK)
    {
        fprintf(logfile, "Can't close the written file: %s\n",
                ssh_get_error(session));
        return E_FILE_CLOSE;
    }
    return E_OK;
}

ESSHERR CSFTPConnector::writeSFTPfile(char *block, size_t blocksize)
{
    size_t nwritten = sftp_write(file, block, blocksize);
    if (nwritten != blocksize)
    {
        fprintf(logfile, "Can't write data to file: %s\n",
            ssh_get_error(session));
        //sftp_close(file);
        transferred = transferred + nwritten;
        return E_WRITE_ERR;
    }

    transferred = transferred + nwritten;
    return E_OK;
}

ESSHERR CSFTPConnector::readSFTPfile(char *block, size_t len, size_t *bytesread)
{
    DWORD readbytes;
    *bytesread = 0;
    if (len <= 0)
        return E_INVALID_PARAMS;
    if (bytesread == NULL || block == NULL)
        return E_INVALID_PARAMS;

    readbytes = sftp_read(file, block, len);
    if (readbytes < 0)
    {
        fprintf(logfile, "Can't read  from  remote file: %s  %s\n", filename.c_str(), ssh_get_error(session));
        *bytesread = 0;
        return E_SFTP_READ_ERR;
    }

    if (readbytes <  len)
    {
        *bytesread = readbytes;
        transferred = transferred + readbytes;
        return E_SFTP_READ_EOF;
    }

    *bytesread = readbytes;
    transferred = transferred + readbytes;

    return E_OK;
}

ESSHERR CSFTPConnector::readSFTPfile(char *block, __int64 len, DWORD *bytesread)
{
    DWORD readbytes;
    *bytesread = 0;
    if (len <= 0)
        return E_INVALID_PARAMS;
    if (bytesread == NULL || block == NULL)
        return E_INVALID_PARAMS;

    readbytes = sftp_read(file, block, len);
    if (readbytes < 0)
    {
        fprintf(logfile, "Can't read  from  remote file: %s  %s\n", filename.c_str(), ssh_get_error(session));
        *bytesread = 0;
        return E_SFTP_READ_ERR;
    }

    if (readbytes <  len)
    {
        *bytesread = readbytes;
        return E_SFTP_READ_EOF;
    }

    *bytesread = readbytes;
    transferred = transferred + readbytes;

    return E_OK;
}

ESSHERR CSFTPConnector::createSFTPfile(char *fn)
{
    int access_type = O_CREAT | O_RDWR;
    int rc, nwritten;

    filename = string(fn);
    file = sftp_open(sftp, fn,
        access_type, S_IWRITE);
    if (file == NULL)
    {
        fprintf(logfile, "Can't open file for writing: %s\n",
                ssh_get_error(session));
        return E_FILEOPEN_WRITE;
    }
    return E_OK;
}

ESSHERR CSFTPConnector::rdopen_existing_SFTPfile(char *fn)
{
    int access_type = O_RDONLY;
    int rc, nwritten;

    filename = string(fn);
    file = sftp_open(sftp, fn,
        access_type, S_IREAD);
    if (file == NULL)
    {
        fprintf(logfile, "Can't open file for writing: %s\n",
                ssh_get_error(session));
        return E_FILEOPEN_RDONLY;
    }
    return E_OK;
}

ESSHERR CSFTPConnector::openSFTPfile(char *fn)
{
    int access_type = O_RDONLY;
    int rc, nwritten;

    filename = string(fn);
    file = sftp_open(sftp, fn,
        access_type, S_IWRITE);
    if (file == NULL)
    {
        fprintf(logfile, "Can't open file for writing: %s\n",
            ssh_get_error(session));
        return E_FILE_OPEN_READ;
    }
    return E_OK;
}

ESSHERR CSFTPConnector::Makedir(char *newdir)
{
    int rc;
    rc = sftp_mkdir(sftp, newdir, S_IFDIR);
    if (rc != SSH_OK)
    {
        if (sftp_get_error(sftp) != SSH_FX_FILE_ALREADY_EXISTS)
        {
            fprintf(logfile, "Can't create directory: %s\n",
                ssh_get_error(session));
            return E_CREATE_DIR;
        }
    }
    return E_OK;
}

SFTPConnector::CSFTPConnector()
{
    //libssh2_init(0);
    session = ssh_new();
    if (session == NULL)
    {
        Err = E_SESSION_ALOC;
        errstring = L"Could not allocate a session.";

    }
    wcscpy(hostname, L"localhost");
    wcscpy(username, L"User");
    wcscpy(password, L"Password");
    wcscpy(basedir, L".\\");
    port = 22;
    verbosity = SSH_LOG_RARE;
    filesize = 0;
    transferred = 0;

    pause = false;
    transferstatus = ES_NONE;
    logfile = stderr;
}


CSFTPConnector::CSFTPConnector(wchar_t *dir, wchar_t *hn, int hostport, wchar_t *un, wchar_t *pass)
{
    session = ssh_new();

    if (session == NULL)
    {
        Err = E_SESSION_ALOC;
        errstring = L"Could not allocate a session.";
    }
    wcscpy(hostname, hn);
    wcscpy(username, un);
    wcscpy(password, pass);
    wcscpy(basedir, dir);
    port = hostport;
    verbosity = SSH_LOG_RARE;
    filesize = 0;
    transferred = 0;

    pause = false;
    transferstatus = ES_NONE;
    logfile = stderr;
}

ESSHERR CSFTPConnector::InitSFTP()
{
    int rc;
    sftp = sftp_new(session);
    if (session == NULL)
    {
        Err = E_SFTP_ALLOC;
        errstring = L"Could not allocate a sftp session.";
    }

    rc = sftp_init(sftp);
    if (rc != SSH_OK)
    {
        fprintf(logfile, "Error initializing SFTP session: %s.\n",
            sftp_get_error(sftp));
        sftp_free(sftp);
        return E_INIT_SFTP;
    }

    return E_OK;
}

ESSHERR CSFTPConnector::ConnectSession()
{
    char temp[SHORT_BUFF_LEN];
    size_t n_of_chars;
    wcstombs_s(&n_of_chars, temp, SHORT_BUFF_LEN, (const wchar_t *)password, SHORT_BUFF_LEN);
    int ir;

    ir = ssh_connect(session);
    if (ir != SSH_OK) {
        errstring = L"Could not connect the ssh session.";
        return E_SSH_CONNECT_ERR;
    }

    ir = ssh_userauth_password(session, NULL, temp);
    if (ir != SSH_OK) {
        errstring = L"Could not connect the ssh session.";
        return E_SSH_CONNECT_ERR;
    }
    return E_OK;
}

ESSHERR CSFTPConnector::InitSession()
{
    char temp[SHORT_BUFF_LEN];
    size_t n_of_chars;
    wcstombs_s(&n_of_chars, temp, SHORT_BUFF_LEN, (const wchar_t *) hostname, SHORT_BUFF_LEN);
    ssh_options_set(session, SSH_OPTIONS_HOST, temp);
    ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
    ssh_options_set(session, SSH_OPTIONS_PORT, &port);
    wcstombs_s(&n_of_chars, temp, SHORT_BUFF_LEN, (const wchar_t *)username, SHORT_BUFF_LEN);
    ssh_options_set(session, SSH_OPTIONS_USER, temp);
    wcstombs_s(&n_of_chars, temp, SHORT_BUFF_LEN, (const wchar_t *)basedir, SHORT_BUFF_LEN);
    ssh_options_set(session, SSH_OPTIONS_SSH_DIR, temp);

    return E_OK;
}

CSFTPConnector::~CSFTPConnector()
{
    sftp_free(sftp);
    ssh_disconnect(session);
    ssh_free(session);

    return;
}

You can use libssh for sftp. I put some code here for you which has Pause/Resume and works on Windows. For Linux, you need to replace local file handling functions. I cannot copy the entire class because it will exceed this website limit. Change username and password and hostname to proper equivalents of your SFTP server:

int main(array<System::String ^> ^args)
{
    //Console::WriteLine(L"Hello World");

    pSFTPConnector  sshc = new  SFTPConnector(L".\\", L"127.0.0.1", 22, L"iman", L"iman");  // Change the hostname, port, username, password to your SFTP server, your credentials

    //FILE *nullfile = fopen("null", "w");
    //sshc->setLogFile(nullfile);
    sshc->setVerbosity(SSH_LOG_RARE);        // You can change the verbosity as appropriate for you

    int i = sshc->InitSession();
    i = sshc->ConnectSession();
    i = sshc->InitSFTP();

    //i = sshc->SFTPrename("renamed_myfile.txt", "myfile.txt");  // Change these file names
    //i = sshc->Makedir("sftpdir");
    //i = sshc->testUploadFile("myfile2.txt", "1234567890testfile");

    // Change these file names to whatever appropriate
    //i = sshc->SFTPget("c:\\testdir\\Got_CAR_HIRE_FINAL_test.jpg", "CAR_HIRE_FINAL_test.jpg", 64*1024);
    i = sshc->SFTPget("c:\\testdir\\get_downloaded_CAR_HIRE_FINAL.jpg", "CAR_HIRE_FINAL.jpg", 64 *1024);
    i = sshc->SFTPreget("c:\\testdir\\reget_downloaded_CAR_HIRE_FINAL.jpg", "CAR_HIRE_FINAL.jpg", 64 * 1024);
    i = sshc->SFTPput("c:\\testdir\\CAR_HIRE_FINAL.jpg", "put_CAR_HIRE_FINAL.jpg", 64 * 1024);
    i = sshc->SFTPreput("c:\\testdir\\CAR_HIRE_FINAL.jpg", "reput_CAR_HIRE_FINAL.jpg", 64 * 1024);

    delete sshc;
    return 0;
}

typedef enum sshconerr {
    E_OK = 1, E_SESSION_ALOC = -1, E_SSH_CONNECT_ERR = -2, E_SFTP_ALLOC = -3, E_INIT_SFTP = -4, E_CREATE_DIR = -5, E_FILEOPEN_WRITE = -6, E_WRITE_ERR = -7,
    E_FILE_CLOSE = -8, E_FILE_OPEN_READ = -9, E_INVALID_PARAMS = -10, E_SFTP_ERR = -11, E_SFTP_READ_ERR = -12, E_SFTP_READBYTES_ERR = -13, E_GET_FILEINF = -14,
    E_LOCAL_FILE_NOTFOUND = -15, E_RENAME_ERR = -16, E_MEM_ALLOC = -17, E_LOCAL_FILE_READ = -18, E_LOCAL_FILE_RDWR = -19, E_REMOTEFILE_SEEK = -20,
    E_REMOTE_FILE_OPEN = -21, E_DELETE_ERR = -22, E_RENAME_LOCAL_FILE = -23, E_LOCAL_DELETE_FILE = -24, E_FILEOPEN_RDONLY = -25, E_SFTP_READ_EOF = -26,
    E_UNKNOWN = -999
} ESSHERR;


// Status of transfers;
typedef enum sftpstat{ES_DONE=0, ES_INPROGRESS, ES_FAILED, ES_STARTING, ES_PAUSED, ES_RESUMING, ES_CANCELLED,  ES_NONE  } ESFTPSTAT;

using namespace std;


// Statistics about the transfer;
typedef struct transferstatstruct {
    string remote_file_name;
    string local_file_name;
    __int64 total_size;
    __int64 transferred;
    __int64 averagebps;
    long long seconds_elapsed;
    long long seconds_remained;
    int percent;
    ESFTPSTAT transferstate;
} TTransStat;


#define E_SESSION_NEW -1

// These libraries are required
#pragma comment(lib, "ssh.lib")

// This is the main class that does the majority of the work

typedef class CSFTPConnector {

    private:
    ssh_session  session;             // SSH session
    sftp_session sftp;                // SFTP session
    sftp_file file;                   // Structure for a remote file
    FILE *localfile;                  // Not used on Windows, but it could be local file pointer in Unix
    FILE *logfile;                    // The file for writing logs, default is set to stderr
    string filename;                  // File name of the transfer;
    string localfilename;             // File name of local file;
    string tempfilename;              // A temporary file name will be used during the transfer which is renamed when transfer is completed.
    ESFTPSTAT transferstatus;         // State of the transfer which has one of the above values (ESFTPSTAT)
    time_t transferstarttime;         // Time of start of the transfer
    wchar_t username[SHORT_BUFF_LEN];
    wchar_t password[SHORT_BUFF_LEN];
    wchar_t hostname[SHORT_BUFF_LEN]; // Hostname of the SFTP server
    wchar_t basedir[SHORT_BUFF_LEN];  // This base directory is the directory of the public and private key structure (NOT USED IN THIS VERSION)
    int port;                         // Port of the server;
    int verbosity;                    // Degree of verbosity of libssh
    __int64  filesize;                // Total number of bytes to be transferred;
    DWORD  local_file_size_hiDWORD;   // Bill Gates cannot accept the file size
                                      // without twisting the programmers, so
                                      // he accepts them in two separate words
                                      // like this
    DWORD  local_file_size_lowDWORD;  // These two DWORDs when connected together comprise a 64 bit file size.
    __int64 lfilesize;                // Local file size
    __int64 rfilesize;                // Remote file size
    __int64 transferred;              // Number of bytes already transferred
    bool pause;                       // Pause flag
    TTransStat stats;                 // Statistics of the transfer
    HANDLE    localfilehandle;        // Windows uses handles to manipulate files. this is the handle to local file.

    ESSHERR CSFTPConnector::rwopen_existing_SFTPfile(char *fn);       // Open a file on remote (server) read/write for upload
    ESSHERR CSFTPConnector::rdopen_existing_SFTPfile(char *fn);       // Open a file on remote (server) read only for download
    ESSHERR createSFTPfile(char *fn);                                 // Create a file on server;
    ESSHERR writeSFTPfile(char *block, size_t blocksize);             // Write a block of data to the  open remote file
    ESSHERR readSFTPfile(char *block, size_t len, size_t *bytesread); // Read a block of data from the  open remote file
    ESSHERR readSFTPfile(char *block, __int64 len, DWORD *bytesread);
    ESSHERR closeSFTPfile();         // Closes the remote file;
    ESSHERR openSFTPfile(char *fn);  // Opens the remote file
    ESSHERR getSFTPfileinfo();       // Gets information about the remote file

    public:
    wstring errstring;        // The string describing last error
    ESSHERR Err;              // Error code of last error
    CSFTPConnector();         // Default constructor;
    CSFTPConnector(wchar_t *dir, wchar_t *hn, int hostport, wchar_t *un, wchar_t *pass);  // Constructor
    void setVerbosity(int v);
    int  getVerbosity();
    ESSHERR InitSession();    // Must be called before doing any transfer
    ESSHERR ConnectSession(); // Connects to the SSH server
    ESSHERR InitSFTP();       // Must be called before doing any transfer
    ESSHERR Makedir(char *newdir);
    ESSHERR testUploadFile(char *fn, char *block);             // Do not use this, only for test purposes for myself
    ESSHERR SFTPput(char *lfn, char *rfn, size_t blocksize);   // Upload a file from start
    ESSHERR SFTPreput(char *lfn, char *rfn, size_t blocksize); // Checks for previouse interrupted transfer, then
                                                               // either continues the previous transfer (if
                                                               // there was any) or starts a new one (UPLOAD)
    ESSHERR SFTPrename(char *newname, char *oldname);          // Renames a remote file( must be closed)
    ESSHERR CSFTPConnector::SFTPdelete(char *remfile);         // Deletes a remote file
    TTransStat getStatus();                                    // Gets statistics of the transfer
    ESSHERR CSFTPConnector::SFTPget(char *lfn, char *rfn, size_t blocksize);    // Downloads a file from the SFTP server
    ESSHERR CSFTPConnector::SFTPreget(char *lfn, char *rfn, size_t blocksize);  // Checks for a previous interrupted transfer,
                                                                                // then either continues the previous transfer
                                                                                // (if there was any) or starts a new one (DOWNLOAD).
    void CancelTransfer();
    void PauseTransfer();
    void setLogFile(FILE *logf); // Sets the log file. If not set, standard
                                 // error will be used. By default.
    void CloseLocalFile();
    void CloseRemoteFile();

    ~CSFTPConnector();
} SFTPConnector, *pSFTPConnector;

void CSFTPConnector::CloseLocalFile()
{
    CloseHandle(localfilehandle);
}


void CSFTPConnector::CloseRemoteFile()
{
    sftp_close(file);
}

void CSFTPConnector::setLogFile(FILE *logf)
{
    logfile = logf;
}

void CSFTPConnector::CancelTransfer()
{
    transferstatus = ES_CANCELLED;
}

void CSFTPConnector::PauseTransfer()
{
    transferstatus = ES_PAUSED;
    pause = true;
}

//----------------------------------------

ESSHERR CSFTPConnector::SFTPget(char *lfn, char *rfn, size_t blocksize)
{
    DWORD result;
    int rc;
    BOOL bresult;
    DWORD bytesread;
    filesize = 0;
    transferred = 0;

    pause = false;
    transferstatus = ES_NONE;
    char *block;
    struct stat st;
    wchar_t temp[SHORT_BUFF_LEN];
    size_t tempsize;
    wstring wlfn;
    int loopcounter = 0;

    localfilename = lfn;

    filename = rfn;

    tempfilename = string(lfn) + ".sftp_temp";
    mbstowcs_s(&tempsize, temp, tempfilename.c_str(), SHORT_BUFF_LEN);

    localfilehandle = CreateFile(temp, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (localfilehandle == INVALID_HANDLE_VALUE)
    {
        transferstatus = ES_FAILED;
        errstring = L"Could not open local file:" + wstring(temp) + L" for read and write";
        Err = E_LOCAL_FILE_RDWR;
        return E_LOCAL_FILE_RDWR;
    }

    lfilesize = 0;
    transferred = 0;

    block = (char*)malloc(blocksize + 1);
    if (block == NULL) {
        Err = E_MEM_ALLOC;
        transferstatus = ES_FAILED;
        errstring = L"Could not allocate memory for file block size";
        CloseLocalFile();
        return E_MEM_ALLOC;
    }

    result = rdopen_existing_SFTPfile((char *)rfn);

    if (result == E_OK) {
        getSFTPfileinfo();
        filesize = rfilesize;
    }
    else
    {
        Err = E_REMOTE_FILE_OPEN;
        transferstatus = ES_FAILED;
        errstring = L"Could not open remote file";
        CloseLocalFile();
        delete block;
        return E_REMOTEFILE_SEEK;
    }

    transferstatus = ES_STARTING;

    sftp_file_set_blocking(file);
    transferstarttime = time(NULL);
    transferstatus = ES_INPROGRESS;

    while (transferstatus != ES_FAILED &&
           transferstatus != ES_PAUSED &&
           transferstatus != ES_CANCELLED &&
           transferstatus != ES_DONE)
    {
        loopcounter++;

        result = readSFTPfile(block, blocksize, (size_t *)&bytesread);
        if (result != E_OK && result!= E_SFTP_READ_EOF)
        {
            errstring = L"Error reading from remote SFTP server file.";
            Err = (ESSHERR)result;
            transferstatus = ES_FAILED;
            CloseRemoteFile();
            CloseLocalFile();
            delete block;
            return (ESSHERR)result;
        }
        if (result == E_SFTP_READ_EOF)
            transferstatus = ES_DONE;
        fprintf(logfile, "Read %d bytes from input file. Number of packets: %d, %llu from %llu bytes\n", bytesread, loopcounter, transferred, filesize);

        bresult = WriteFile(localfilehandle, (LPVOID)block, bytesread, &bytesread, NULL);
        if (bytesread < blocksize)
        {
            if (bresult == FALSE)
            {
                errstring = L"Error writing to local file.";
                Err = E_LOCAL_FILE_RDWR;
                transferstatus = ES_FAILED;
                CloseRemoteFile();
                CloseLocalFile();
                delete block;
                return E_LOCAL_FILE_RDWR;
            }
            else if (bytesread == 0)
            {
                errstring = L"Transfer done.";
                Err = E_OK;
                transferstatus = ES_DONE;
                continue;
            }
        }

        Err = E_OK;

        if (pause == true)
            transferstatus = ES_PAUSED;
        if (bresult == TRUE &&  bytesread == 0)
        {
            // At the end of the file
            transferstatus = ES_DONE;
        }
        Sleep(BLOCKTRANSDELAY);
        if (loopcounter % 331 == 0)
            Sleep(77 * BLOCKTRANSDELAY);
        if (loopcounter % 3331 == 0)
            Sleep(777 * BLOCKTRANSDELAY);
    }

    // Closing files
    result = closeSFTPfile();
    CloseHandle(localfilehandle);

    Sleep(1000);

    if (transferstatus == ES_DONE)
    {
        wchar_t temp2[SHORT_BUFF_LEN];
        mbstowcs_s(&tempsize, temp2, lfn, SHORT_BUFF_LEN);
        bresult = MoveFile(temp, temp2);
        if (bresult != TRUE)
        {
            Err = E_RENAME_LOCAL_FILE;
            errstring = L"Could not rename local file: " + wstring(temp);
            transferstatus = ES_FAILED;
            delete block;
            return E_RENAME_LOCAL_FILE;
        }
    }

    if (transferstatus == ES_CANCELLED)
    {
        wchar_t temp2[SHORT_BUFF_LEN];
        mbstowcs_s(&tempsize, temp2, lfn, SHORT_BUFF_LEN);
        bresult = DeleteFile(temp);
        if (bresult != TRUE)
        {
            Err = E_LOCAL_DELETE_FILE;
            errstring = L"Could not rename local file: " + wstring(temp);
            transferstatus = ES_FAILED;
            delete block;
            return E_LOCAL_DELETE_FILE;
        }
    }
    delete block;
    return (ESSHERR) result;
}

TTransStat CSFTPConnector::getStatus()
{
    stats.seconds_elapsed = time(NULL) - transferstarttime;
    stats.averagebps = (transferred * 8) / stats.seconds_elapsed;
    if (filesize > 0) {
        stats.percent = (transferred *100)/ filesize;
        stats.seconds_remained = ((filesize - transferred) * 8) / stats.averagebps;
    }
    else
    {
        stats.percent = -1;
        stats.seconds_remained = -1;
    }
    stats.total_size = filesize;
    stats.transferstate = transferstatus;
    stats.remote_file_name = filename;
    stats.local_file_name = localfilename;

    return stats;
}

ESSHERR CSFTPConnector::SFTPrename(char *newname, char *oldname)
{
    int rc = sftp_rename(sftp, oldname, newname);
    if (rc != SSH_OK) {
        return E_RENAME_ERR;
    }

    return E_OK;
}


ESSHERR CSFTPConnector::SFTPdelete(char *remfile)
{
    int rc = sftp_unlink(sftp, remfile);
    if (rc != SSH_OK) {
        return E_DELETE_ERR;
    }
    return E_OK;
}


ESSHERR CSFTPConnector::SFTPreput(char *lfn, char *rfn, size_t blocksize)
{
    ESSHERR result;
    BOOL  bresult;
    DWORD bytesread;
    filesize = 0;
    transferred = 0;

    pause = false;
    transferstatus = ES_NONE;
    char *block;
    struct stat st;
    wchar_t temp[SHORT_BUFF_LEN];
    size_t tempsize;
    wstring wlfn;
    int loopcounter = 0;

    localfilename = lfn;
    //wlfn = wstring(lfn);
    //localfile = fopen(lfn, L"r");
    filename = rfn;
    mbstowcs_s(&tempsize, temp, lfn, SHORT_BUFF_LEN);

    //filesize = getFileSize(localfilename);

    /*if (filesize < 0) {
        transferstatus = ES_FAILED;
        Err = E_LOCAL_FILE_NOTFOUND;
        return E_LOCAL_FILE_NOTFOUND;
    }*/

    localfilehandle = CreateFile(temp, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (localfilehandle == INVALID_HANDLE_VALUE)
    {
        transferstatus = ES_FAILED;
        Err = E_LOCAL_FILE_NOTFOUND;
        return E_LOCAL_FILE_NOTFOUND;
    }
    local_file_size_lowDWORD = GetFileSize(localfilehandle, &local_file_size_hiDWORD);
    filesize = (local_file_size_hiDWORD * 0x100000000) + local_file_size_lowDWORD;

    if (filesize < 0) {
        transferstatus = ES_FAILED;
        Err = E_LOCAL_FILE_NOTFOUND;
        CloseLocalFile();
        return E_LOCAL_FILE_NOTFOUND;
    }

    block = (char*)malloc(blocksize + 1);
    if (block == NULL) {
        Err = E_MEM_ALLOC;
        transferstatus = ES_FAILED;
        errstring = L"Could not allocate memory for file block size";
        CloseLocalFile();
        return E_MEM_ALLOC;
    }

    tempfilename = string(rfn) + ".sftp_temp";

    result = rwopen_existing_SFTPfile((char *)tempfilename.c_str());
    if (result == E_OK) {
        getSFTPfileinfo();
        sftp_seek64(file, rfilesize);
        __int64 tempi64 = rfilesize & 0x00000000FFFFFFFF;
        DWORD dwlow = tempi64;
        tempi64 = (rfilesize & 0x7FFFFFFF00000000);
        tempi64 = tempi64 >> 32;
        long  dwhi = tempi64;
        DWORD dwResult = SetFilePointer(localfilehandle, dwlow, &dwhi, FILE_BEGIN);
        if (dwResult == INVALID_SET_FILE_POINTER)
        {
            transferstatus = ES_FAILED; Err = result;  return result;
        }
        transferstatus = ES_RESUMING;
        transferred = rfilesize;
    }
    else{
        result = createSFTPfile((char *)tempfilename.c_str());
        transferstatus = ES_STARTING;
        if (result != E_OK) {
            transferstatus = ES_FAILED;
            Err = result;
            CloseLocalFile();
            return result;
        }
    }
    sftp_file_set_blocking(file);
    transferstarttime = time(NULL);
    transferstatus = ES_INPROGRESS;

    while (transferstatus != ES_FAILED &&
           transferstatus != ES_PAUSED &&
           transferstatus != ES_DONE)
    {
        loopcounter++;
        bresult = ReadFile(localfilehandle, (LPVOID)block, blocksize, &bytesread, NULL);
        fprintf(logfile, "Read %d bytes from input file. Number of packets: %d, %llu from %llu bytes\n", bytesread, loopcounter, transferred, filesize);
        if (bytesread < blocksize)
        {
            if (bresult == FALSE)
            {
                errstring = L"Error reading from local file.";
                Err = E_LOCAL_FILE_READ;
                transferstatus = ES_FAILED;
                CloseRemoteFile();
                CloseLocalFile();
                return E_LOCAL_FILE_READ;
            }
            else if (bytesread == 0)
            {
                errstring = L"Transfer done.";
                Err = E_OK;
                transferstatus = ES_DONE;
                continue;
            }
        }

        result = writeSFTPfile(block, bytesread);
        if (result != E_OK && bytesread>0)
        {
            errstring = L"Error transmitting to remote SFTP server file.";
            Err = result;
            transferstatus = ES_FAILED;
            CloseRemoteFile();
            CloseLocalFile();
            return result;
        }

        Err = E_OK;
        //transferred = transferred + bytesread;
        if (pause == true)
            transferstatus = ES_PAUSED;
        if (bresult == TRUE &&  bytesread == 0)
        {
            // At the end of the file
            transferstatus = ES_DONE;
        }
        Sleep(BLOCKTRANSDELAY);
        if (loopcounter % 331 == 0)
            Sleep(77 * BLOCKTRANSDELAY);
        if (loopcounter % 3331 == 0)
            Sleep(777 * BLOCKTRANSDELAY);
    }

    CloseRemoteFile();
    CloseLocalFile();
    Sleep(1000);

    if (transferstatus == ES_CANCELLED)
    {
        result = SFTPdelete((char *)tempfilename.c_str());
        if (bresult != E_OK)
        {
            Err = E_DELETE_ERR;
            errstring = L"Could not delete remote file.";
            transferstatus = ES_FAILED;
            return E_DELETE_ERR;
        }
    }
    if (transferstatus == ES_DONE)
        result = SFTPrename(rfn, (char *)tempfilename.c_str());
    delete block;
    return result;
}


ESSHERR CSFTPConnector::getSFTPfileinfo()
{
    sftp_attributes fileinf = sftp_fstat(file);

    if (fileinf == NULL) {
        return E_GET_FILEINF;
    }

    rfilesize = fileinf->size;

    sftp_attributes_free(fileinf);
    return E_OK;
}

ESSHERR CSFTPConnector::closeSFTPfile()
{
    int rc = sftp_close(file);
    if (rc != SSH_OK)
    {
        fprintf(logfile, "Can't close the written file: %s\n",
                ssh_get_error(session));
        return E_FILE_CLOSE;
    }
    return E_OK;
}

ESSHERR CSFTPConnector::writeSFTPfile(char *block, size_t blocksize)
{
    size_t nwritten = sftp_write(file, block, blocksize);
    if (nwritten != blocksize)
    {
        fprintf(logfile, "Can't write data to file: %s\n",
            ssh_get_error(session));
        //sftp_close(file);
        transferred = transferred + nwritten;
        return E_WRITE_ERR;
    }

    transferred = transferred + nwritten;
    return E_OK;
}

ESSHERR CSFTPConnector::readSFTPfile(char *block, size_t len, size_t *bytesread)
{
    DWORD readbytes;
    *bytesread = 0;
    if (len <= 0)
        return E_INVALID_PARAMS;
    if (bytesread == NULL || block == NULL)
        return E_INVALID_PARAMS;

    readbytes = sftp_read(file, block, len);
    if (readbytes < 0)
    {
        fprintf(logfile, "Can't read  from  remote file: %s  %s\n", filename.c_str(), ssh_get_error(session));
        *bytesread = 0;
        return E_SFTP_READ_ERR;
    }

    if (readbytes <  len)
    {
        *bytesread = readbytes;
        transferred = transferred + readbytes;
        return E_SFTP_READ_EOF;
    }

    *bytesread = readbytes;
    transferred = transferred + readbytes;

    return E_OK;
}

ESSHERR CSFTPConnector::readSFTPfile(char *block, __int64 len, DWORD *bytesread)
{
    DWORD readbytes;
    *bytesread = 0;
    if (len <= 0)
        return E_INVALID_PARAMS;
    if (bytesread == NULL || block == NULL)
        return E_INVALID_PARAMS;

    readbytes = sftp_read(file, block, len);
    if (readbytes < 0)
    {
        fprintf(logfile, "Can't read  from  remote file: %s  %s\n", filename.c_str(), ssh_get_error(session));
        *bytesread = 0;
        return E_SFTP_READ_ERR;
    }

    if (readbytes <  len)
    {
        *bytesread = readbytes;
        return E_SFTP_READ_EOF;
    }

    *bytesread = readbytes;
    transferred = transferred + readbytes;

    return E_OK;
}

ESSHERR CSFTPConnector::createSFTPfile(char *fn)
{
    int access_type = O_CREAT | O_RDWR;
    int rc, nwritten;

    filename = string(fn);
    file = sftp_open(sftp, fn,
        access_type, S_IWRITE);
    if (file == NULL)
    {
        fprintf(logfile, "Can't open file for writing: %s\n",
                ssh_get_error(session));
        return E_FILEOPEN_WRITE;
    }
    return E_OK;
}

ESSHERR CSFTPConnector::rdopen_existing_SFTPfile(char *fn)
{
    int access_type = O_RDONLY;
    int rc, nwritten;

    filename = string(fn);
    file = sftp_open(sftp, fn,
        access_type, S_IREAD);
    if (file == NULL)
    {
        fprintf(logfile, "Can't open file for writing: %s\n",
                ssh_get_error(session));
        return E_FILEOPEN_RDONLY;
    }
    return E_OK;
}

ESSHERR CSFTPConnector::openSFTPfile(char *fn)
{
    int access_type = O_RDONLY;
    int rc, nwritten;

    filename = string(fn);
    file = sftp_open(sftp, fn,
        access_type, S_IWRITE);
    if (file == NULL)
    {
        fprintf(logfile, "Can't open file for writing: %s\n",
            ssh_get_error(session));
        return E_FILE_OPEN_READ;
    }
    return E_OK;
}

ESSHERR CSFTPConnector::Makedir(char *newdir)
{
    int rc;
    rc = sftp_mkdir(sftp, newdir, S_IFDIR);
    if (rc != SSH_OK)
    {
        if (sftp_get_error(sftp) != SSH_FX_FILE_ALREADY_EXISTS)
        {
            fprintf(logfile, "Can't create directory: %s\n",
                ssh_get_error(session));
            return E_CREATE_DIR;
        }
    }
    return E_OK;
}

SFTPConnector::CSFTPConnector()
{
    //libssh2_init(0);
    session = ssh_new();
    if (session == NULL)
    {
        Err = E_SESSION_ALOC;
        errstring = L"Could not allocate a session.";

    }
    wcscpy(hostname, L"localhost");
    wcscpy(username, L"User");
    wcscpy(password, L"Password");
    wcscpy(basedir, L".\\");
    port = 22;
    verbosity = SSH_LOG_RARE;
    filesize = 0;
    transferred = 0;

    pause = false;
    transferstatus = ES_NONE;
    logfile = stderr;
}


CSFTPConnector::CSFTPConnector(wchar_t *dir, wchar_t *hn, int hostport, wchar_t *un, wchar_t *pass)
{
    session = ssh_new();

    if (session == NULL)
    {
        Err = E_SESSION_ALOC;
        errstring = L"Could not allocate a session.";
    }
    wcscpy(hostname, hn);
    wcscpy(username, un);
    wcscpy(password, pass);
    wcscpy(basedir, dir);
    port = hostport;
    verbosity = SSH_LOG_RARE;
    filesize = 0;
    transferred = 0;

    pause = false;
    transferstatus = ES_NONE;
    logfile = stderr;
}

ESSHERR CSFTPConnector::InitSFTP()
{
    int rc;
    sftp = sftp_new(session);
    if (session == NULL)
    {
        Err = E_SFTP_ALLOC;
        errstring = L"Could not allocate a sftp session.";
    }

    rc = sftp_init(sftp);
    if (rc != SSH_OK)
    {
        fprintf(logfile, "Error initializing SFTP session: %s.\n",
            sftp_get_error(sftp));
        sftp_free(sftp);
        return E_INIT_SFTP;
    }

    return E_OK;
}

ESSHERR CSFTPConnector::ConnectSession()
{
    char temp[SHORT_BUFF_LEN];
    size_t n_of_chars;
    wcstombs_s(&n_of_chars, temp, SHORT_BUFF_LEN, (const wchar_t *)password, SHORT_BUFF_LEN);
    int ir;

    ir = ssh_connect(session);
    if (ir != SSH_OK) {
        errstring = L"Could not connect the ssh session.";
        return E_SSH_CONNECT_ERR;
    }

    ir = ssh_userauth_password(session, NULL, temp);
    if (ir != SSH_OK) {
        errstring = L"Could not connect the ssh session.";
        return E_SSH_CONNECT_ERR;
    }
    return E_OK;
}

ESSHERR CSFTPConnector::InitSession()
{
    char temp[SHORT_BUFF_LEN];
    size_t n_of_chars;
    wcstombs_s(&n_of_chars, temp, SHORT_BUFF_LEN, (const wchar_t *) hostname, SHORT_BUFF_LEN);
    ssh_options_set(session, SSH_OPTIONS_HOST, temp);
    ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
    ssh_options_set(session, SSH_OPTIONS_PORT, &port);
    wcstombs_s(&n_of_chars, temp, SHORT_BUFF_LEN, (const wchar_t *)username, SHORT_BUFF_LEN);
    ssh_options_set(session, SSH_OPTIONS_USER, temp);
    wcstombs_s(&n_of_chars, temp, SHORT_BUFF_LEN, (const wchar_t *)basedir, SHORT_BUFF_LEN);
    ssh_options_set(session, SSH_OPTIONS_SSH_DIR, temp);

    return E_OK;
}

CSFTPConnector::~CSFTPConnector()
{
    sftp_free(sftp);
    ssh_disconnect(session);
    ssh_free(session);

    return;
}
喵星人汪星人 2024-07-11 21:47:47

尝试 Libcurl

libcurl是一个免费且易于使用的客户端URL传输库,支持DICT、FILE、> FTP、FTPS、Gopher、HTTP、HTTPS、IMAP、IMAPS、LDAP、LDAPS、POP3、POP3S、RTMP、RTSP、SCP、SFTP、SMTP、SMTPS、Telnet 和 TFTP。 libcurl 支持 SSL 证书、HTTP POST、HTTP PUT、FTP 上传、基于 HTTP 表单的上传、代理、cookie、用户+密码身份验证(基本、摘要、NTLM、协商、Kerberos)、文件传输恢复、http 代理隧道等等!< /p>

libcurl 具有高度可移植性,它在多种平台上的构建和工作方式相同,包括 Solaris、NetBSD、FreeBSD、OpenBSD、Darwin、HPUX、IRIX、AIX、Tru64、Linux、UnixWare、HURD、Windows、Amiga、OS/2、 BeOs、Mac OS X、Ultrix、QNX、OpenVMS、RISC OS、Novell NetWare、DOS 等...

Try Libcurl

libcurl is a free and easy-to-use client-side URL transfer library, supporting DICT, FILE, > FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet and TFTP. libcurl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, Kerberos), file transfer resume, http proxy tunneling and more!

libcurl is highly portable, it builds and works identically on numerous platforms, including Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HPUX, IRIX, AIX, Tru64, Linux, UnixWare, HURD, Windows, Amiga, OS/2, BeOs, Mac OS X, Ultrix, QNX, OpenVMS, RISC OS, Novell NetWare, DOS and more...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文