【问题标题】:How to solve FTP timeouts in C# app如何解决 C# 应用程序中的 FTP 超时
【发布时间】:2009-04-24 18:55:24
【问题描述】:

我正在使用以下 C# 代码从远程服务提供商 FTP 传输约 40MB 的 CSV 文件。大约 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;
    }

【问题讨论】:

    标签: c# ftp


    【解决方案1】:

    我尝试按照上面的建议使用 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");
    

    【讨论】:

      【解决方案2】:

      我建议您不要使用 FtpWebRequest 进行 FTP 访问。 FtpWebRequest 是我见过的最脑残的 FTP API。

      目前我使用 FtpClient http://www.codeplex.com/ftpclient

      我在 IndySockets http://www.indyproject.org/index.en.aspx 上也很幸运

      【讨论】:

      • 是的,绝对同意您对 FTPWebRequest API 的评估;只使用它,因为我继承了这段代码,不想做大的改变。只是它的类名中有“Web”这一事实就是一个线索——FTP 与 Web 有关系!我会看看你引用的库。谢谢!
      • 有趣的是来自 CodePlex 的 FtpClient 使用 FTPWebRequest API。并且扩展是不必要的。你应该看看 Socket 类。
      【解决方案3】:

      我还没有在代码级别处理过 FTP,但 FTP 支持恢复。也许你可以让它在超时时自动尝试恢复上传

      【讨论】:

      • 是的,好主意——尽管它可以解决而不是解决根本问题。图形 FTP 客户端很少超时;为什么我的代码会这样做?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-31
      • 1970-01-01
      • 1970-01-01
      • 2017-10-25
      • 1970-01-01
      • 2021-12-15
      相关资源
      最近更新 更多