0

I'm using the libssh library in MFC C++, specifically the SFTP wrapper. I have code working when not using threading, but I want to use AfxBeginThread to allow user action to continue.

I have confirmed I'm passing the exact same filenames and target save paths using the thread or not - I've tested this by hardcoding the file to save and the destination to save directly in BeginDownload().

Is there a specific way the SFTP wrapper for the libssh must be used to let the download perform within a thread? I would like to allow users to download multiple files at the same time from the same instance of the ssh objects, and just launch a new thread each time a file needs to be downloaded.

Here is what I'm using for the actual downloading. m_sftp_sesssion is my sftp_session object created upon logging in.

bool CSFtpManager::BeginDownload(CString filename, CString savefilename)
{
    sftp_dir dir = sftp_opendir(m_sftp_session, "../../../directory");
    sftp_attributes attrs = sftp_readdir(m_sftp_session, dir);

    int access_type = O_RDONLY;
    sftp_file file;
    file = sftp_open(m_sftp_session, "../../../directory/myfile.zip", access_type, 0);

    const char* x2 = ssh_get_error(m_ssh_session);
    if(file == NULL)
    {
        int a;
    }
    int nbytes;
    char buffer[1024];
    FILE * pFile;
    pFile = fopen(CStringA(savefilename), "wb");
    nbytes = sftp_read(file, buffer, sizeof(buffer)); //this is crashing inside a thread
    while(nbytes > 0)
    {
        fwrite(buffer, sizeof(char), sizeof(buffer), pFile);
        nbytes = sftp_read(file, buffer, sizeof(buffer));
    }
    fclose(pFile);
    sftp_close(file);
    return true;
}

Here is my login method where my libssh objects are being set in member variables for later use. Included is a commented line calling my BeginDownload. Calling it outside a thread (i.e. clicking a login button) does work.

bool CSFtpManager::login()
{
    int verbosity = SSH_LOG_PROTOCOL;
    m_ssh_session = ssh_new();
    ssh_options_set(m_ssh_session, SSH_OPTIONS_HOST, "ftp3 host..");
    //setting username and password... 
    ssh_options_set(m_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
    ssh_options_set(m_ssh_session, SSH_OPTIONS_PORT, &m_iPort);

    int x = ssh_connect(m_ssh_session);
    const char* x2 = ssh_get_error(m_ssh_session);


    if(rc != SSH_AUTH_SUCCESS)
    {
        return false;
    }

    m_sftp_session;
    m_sftp_session = sftp_new(m_ssh_session);

    //Calling BeginDownload here does work
    //BeginDownload(L"file.txt", L"T:\\file.txt");
    ... }

Here is what I'm using to call the exact same function via a thread

CWinThread* pThread2 = AfxBeginThread(BeginSFTPDownload, bundle);

And the method being ran via the above:

UINT CMainFrame::BeginSFTPDownload( LPVOID pParam)
{
    pSft->BeginDownload(L"test.txt", L"T:\\test.txt");
    return 0;
}
4

0 回答 0