locked
File download using StremSocket

    Question

  • I am trying to connect to an FTP site using StreamSocket. This is an open site that does not require username/password. I am using the below code and I am able to connect to the server. The ftp server name is just a dummy one. I tested using real ftp sites.

    StreamSocket^ clientSocket = ref new StreamSocket(); HostName^ Host = ref new HostName( "ftp.myftp.com" ); task<void>(clientSocket->ConnectAsync( Host, "ftp" )).

    then([this,clientSocket]( task<void>PrevTask ) { PrevTask.get(); IInputStream^ readStream = clientSocket->InputStream; Buffer^ readBuffer = ref new Buffer( 1024 ); task<IBuffer^>(readStream->ReadAsync(readBuffer, readBuffer->Capacity, InputStreamOptions::Partial)).then([this,readBuffer] (IBuffer^ buffer) { int bytesReceived = readBuffer->Length; DataReader^ Read = DataReader::FromBuffer(readBuffer); String^ K = Read->ReadString( bytesReceived ); // I am able to get the ftp server name here. }); });

    The full path of he file  I want to download is ftp://myftp.com/MyFirstFolder/MySecondFolder/MyExe.exe

    Is there anyway I can access the actual file and read it using StreamSocket?


    • Edited by its_me_here Saturday, September 29, 2012 6:54 PM
    Saturday, September 29, 2012 6:51 PM

Answers

  • Hi its_me_here,

    Yes, the GetResponseInformation method returns null for ftp operations since there is no response information for FTP. For HTTP protocol, the HTTP response does contain the response but in the case of FTP, the only response information is the status code. That's why you are seeing the difference.

    The way to determine if an FTP download was successful is to look at the completion of the async operation. I.e. the async operation started with DownloadOperation.StartAsync() will complete with success when the FTP download completed successfully and it will complete with failure in case of an error. You can also check the DownloadOperation.Progress.Status property to check if the file download was “Completed” or not. If it is completed, it means that the file was successfully downloaded. That way you should be able to check the status of the download and whether it was successful or if it failed.

    Thanks,

    Prashant.

     

    • Marked as answer by its_me_here Tuesday, November 6, 2012 11:26 AM
    Monday, November 5, 2012 6:36 PM
    Moderator

All replies

  • Hello,

    In the above code, you are simply establishing a connection to the FTP Server. Once you are connected to the FTP Server, the FTP server sends you a banner telling the name etc. After that point, you need to actually send FTP commands to the FTP Server to get files etc. In short you will need to implement RFC 959: http://www.ietf.org/rfc/rfc959.txt by yourself and perform operations such as sending the USER/PASS command, followed by sending the RETR command. Once you send the RETR command, you need to open a data socket with the server depending on whether the server supports active or passive transfer. That requires a lot of work.

    Btw, why are you trying to implement the FTP protocol yourself? You can use the BackgroundTransfer API if you just want to perform file downloads. Here is a reference that talks about downloading files using BackgroundTransfer API: http://msdn.microsoft.com/en-us/library/windows/apps/hh452979.aspx

    Thanks,

    Prashant.

    Friday, November 2, 2012 10:46 PM
    Moderator
  • Thank you Prasanth for answering. In fact I have been following FTP download related thread for some time now. Thought the docs say that background transfer can be used for FTP download there is some problem associated with it. Yes, I am able to download from FTP servers using background transfer. Please refer to the below code. The problem is with the section taking response from teh server that decides whether the download is complete or error occured. ie.

    ResponseInformation^ response = opResponse->GetResponseInformation();

    Becoz GetResponseInformation() is null always in the case of FTP. So there is now way I can tell when the download is complete. But the file is successfully downloaded if u check the download location in ur PC. But download from http server works without any issues. I suppose the response information is different for FTP and HTTP and that may be why the problem. Can you please try this code and check what could be the issue? The below code works well for HTTP.

    Windows::Storage::StorageFolder^ folder = ApplicationData::Current->LocalFolder; file_name = "Trial.exe"; task<StorageFile^>(folder->CreateFileAsync(file_name, CreationCollisionOption::ReplaceExisting)) .then([this](StorageFile^ file) { wchar_t msgbuffer[1024] = {0}; BackgroundDownloader^ bd = ref new BackgroundDownloader( ); DownloadOperation^ loader_op = bd->CreateDownload( ref new Uri("ftp site name"), file ); task<DownloadOperation^>(loader_op->StartAsync()).then([this](DownloadOperation^ opCallback) -> DownloadOperation^ { if (opCallback->Progress.HasRestarted) { OutputDebugString( L"Restarted" ); } if (opCallback->Progress.HasResponseChanged) { OutputDebugString( L"Response Changed" ); } return opCallback; }).then([this,&file](DownloadOperation^ opResponse) { wchar_t msgbuffer[1024] = {0}; ResponseInformation^ response = opResponse->GetResponseInformation(); if (response) {

    // Works well for HTTP server.But not for FTP

    if( 200 == response->StatusCode ) { //OK } else { // Failed } } }); });

    BTW you may also refer the below thread I posted and refre to the last post if that is a solution..

    http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/382be788-b2e0-4aef-b6dc-ed6305235f5e


    • Edited by its_me_here Monday, November 5, 2012 7:16 AM
    Monday, November 5, 2012 7:15 AM
  • Hi its_me_here,

    Yes, the GetResponseInformation method returns null for ftp operations since there is no response information for FTP. For HTTP protocol, the HTTP response does contain the response but in the case of FTP, the only response information is the status code. That's why you are seeing the difference.

    The way to determine if an FTP download was successful is to look at the completion of the async operation. I.e. the async operation started with DownloadOperation.StartAsync() will complete with success when the FTP download completed successfully and it will complete with failure in case of an error. You can also check the DownloadOperation.Progress.Status property to check if the file download was “Completed” or not. If it is completed, it means that the file was successfully downloaded. That way you should be able to check the status of the download and whether it was successful or if it failed.

    Thanks,

    Prashant.

     

    • Marked as answer by its_me_here Tuesday, November 6, 2012 11:26 AM
    Monday, November 5, 2012 6:36 PM
    Moderator
  • Thank you Prasanth! I modified the code as you suggested and it now works perfecty well for FTP downloads.
    Tuesday, November 6, 2012 11:26 AM