Как решить тайм-ауты FTP в приложении C # - PullRequest
5 голосов
/ 24 апреля 2009

Я использую следующий код C # для передачи файла CSV ~ 40 МБ от удаленного поставщика услуг. Приблизительно в 50% случаев загрузка зависает и время ожидания истекает. В моем журнале приложений я получаю строку вроде:

> Unable to read data from the transport
> connection: A connection attempt
> failed because the connected party did
> not properly respond after a period of
> time, or established connection failed
> because connected host has failed to
> respond.

Когда я загружаю файл в интерактивном режиме с помощью графического клиента, такого как LeechFTP, загрузка почти никогда не зависает и завершается примерно через 45 секунд. У меня чертовское время, чтобы понять, что происходит не так.

Кто-нибудь может подсказать, как я могу применить этот код, чтобы лучше понять, что происходит, или лучший способ загрузить этот файл? Должен ли я увеличить размер буфера? На сколько? Избегать буферизованных записей на диск и попытаться проглотить весь файл в памяти? Любой совет приветствуется!

...

private void CreateDownloadFile()
    {
        _OutputFile = new FileStream(_SourceFile, FileMode.Create);
    }
public string FTPDownloadFile()
    {
        this.CreateDownloadFile();

        myReq = (FtpWebRequest)FtpWebRequest.Create(new Uri(this.DownloadURI));
        myReq.Method = WebRequestMethods.Ftp.DownloadFile;
        myReq.UseBinary = true;
        myReq.Credentials = new NetworkCredential(_ID, _Password);

        FtpWebResponse myResp = (FtpWebResponse)myReq.GetResponse();
        Stream ftpStream = myResp.GetResponseStream();

        int bufferSize = 2048;
        int readCount;
        byte[] buffer = new byte[bufferSize];
        int bytesRead = 0;
        readCount = ftpStream.Read(buffer, 0, bufferSize);

        while (readCount > 0)
        {
            _OutputFile.Write( buffer, 0, readCount );
            readCount = ftpStream.Read( buffer, 0, bufferSize );

            Console.Write( '.' );    // show progress on the console
            bytesRead += readCount;
        }
        Console.WriteLine();
        logger.logActivity( "    FTP received " + String.Format( "{0:0,0}", bytesRead ) + " bytes" );

        ftpStream.Close();
        _OutputFile.Close();
        myResp.Close();
        return this.GetFTPStatus();
    }

    public string GetFTPStatus()
    {
        return ((FtpWebResponse)myReq.GetResponse()).StatusDescription;
    }

Ответы [ 3 ]

2 голосов
/ 05 октября 2011

Я попытался использовать FTPClient, как предложено выше, и получил ту же ошибку тайм-аута, FTPClient использует FtpWebRequest, поэтому я должен что-то упустить, но не вижу смысла.

После еще одного исследования я обнаружил, что -1 - это значение для бесконечности

Для моей цели можно использовать бесконечность, так что я решил, проблема решена.

Вот мой код:

// получает файл с FTP-сайта.

        FtpWebRequest reqFTP;

        string fileName = @"c:\downloadDir\localFileName.txt";
        FileInfo downloadFile = new FileInfo(fileName);
        string uri = "ftp://ftp.myftpsite.com/ftpDir/remoteFileName.txt";


        FileStream outputStream = new FileStream(fileName, FileMode.Append);

        reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
        reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
        reqFTP.UseBinary = true;
        reqFTP.KeepAlive = false;
        reqFTP.Timeout = -1;
        reqFTP.UsePassive = true;
        reqFTP.Credentials = new NetworkCredential("userName", "passWord");
        FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
        Stream ftpStream = response.GetResponseStream();
        long cl = response.ContentLength;
        int bufferSize = 2048;
        int readCount;
        byte[] buffer = new byte[bufferSize];
        readCount = ftpStream.Read(buffer, 0, bufferSize);
        Console.WriteLine("Connected: Downloading File");
        while (readCount > 0)
        {
            outputStream.Write(buffer, 0, readCount);
            readCount = ftpStream.Read(buffer, 0, bufferSize);
            Console.WriteLine(readCount.ToString());
        }

        ftpStream.Close();
        outputStream.Close();
        response.Close();
        Console.WriteLine("Downloading Complete");
1 голос
/ 24 апреля 2009

Я предлагаю вам не использовать FtpWebRequest для доступа по FTP. FtpWebRequest - самый мёртвый FTP API, который я когда-либо видел.

В настоящее время я использую FtpClient http://www.codeplex.com/ftpclient

Мне также повезло с IndySockets http://www.indyproject.org/index.en.aspx

0 голосов
/ 24 апреля 2009

Я не имел дело с FTP на уровне кода, но FTP поддерживает возобновление. Возможно, вы могли бы автоматически попытаться возобновить загрузку по истечении времени ожидания

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