c# - 使用 c# ftp 方法上传文件导致 webexception。程序重启后问题消失

标签 c# ftp

我有以下问题: 我正在使用 C# ftp 方法自动将文件发送到 FTP 服务器。该程序不断运行,检查预定义的目录。如果它在目录中找到文件,则应该将它们上传到定义的 ftp 服务器。大约有 80 个目录,大部分时间程序都有事情要做。一切正常,除了以下情况:

  1. 正在上传文件。
  2. 上传时出现错误:远程主机宕机、超出配额或类似情况。
  3. 尝试再次上传文件,但再次出现错误。
  4. 第三次,第四次,...尝试上传文件,然后这行代码:

    流请求流 = ftpRequest.GetRequestStream();

抛出状态为未定义的 WebException,并且描述:已达到此操作的时间限制(或类似的东西 - 我不得不从波兰语翻译)。抛出此 WebException 时,对其他服务器(来自不同目录的文件)的 ftp 请求成功,因此看起来只有与这一个 ftp 服务器的连接有问题。

这一切都导致不再尝试上传文件成功。但是,可以通过其他 ftp 客户端上传此文件。当我重新启动程序时,一切运行顺利。我应该以某种方式手动释放 ftp 资源吗?我正在使用 FtpWebRequest 的 KeepAlive 属性设置为 true..

如果有人能阐明这个问题,我将不胜感激。

编辑:

我按照David的提示,找到requestStream上没有调用Close()方法的地方,修复了,但是问题又出现了。

然后我会粘贴一些代码。这是将文件上传到服务器的方法的一部分。如果失败,则会进行另一次尝试,例如:

while (retryCounter++ < retryNumber)
{
  //upload file,
  //if succeeded, break
}

在 while block 中有:

FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(remoteFileName);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.Credentials = new NetworkCredential(UserName, Password);
ftpRequest.ReadWriteTimeout = SendTimeout;
ftpRequest.Timeout = ConnectTimeout;
ftpRequest.KeepAlive = true;
ftpRequest.Proxy = null;
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;

Stream requestStream = null;

try
{

  using (MemoryStream fileStream = new MemoryStream(localFile))
  {
    byte[] buffer = new byte[BufferSize];

    int readCount = fileStream.Read(buffer, 0, BufferSize);
    int bytesSentCounter = 0;

     while (readCount > 0)
     {
         requestStream.Write(buffer, 0, readCount);
         bytesSentCounter += readCount;

         readCount = fileStream.Read(buffer, 0, BufferSize);
         System.Threading.Thread.Sleep(100);

     }
}

requestStream.Close();
requestStream = null;

FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
FtpStatusCode code = response.StatusCode;
string description = response.StatusDescription;
response.Close();

_logger.Information("Upload file result : status code {0}, status description {1}", code, description);

if (code == FtpStatusCode.ClosingData)
{
    _logger.Information("File {0} uploaded successfully", localFileName);
}  
else
{
    _logger.Error("Uploading file {0} did not succeed. Status code is {1}, description  {2}", localFileName, code, description);
}

}   
catch (WebException ex)
{

    if (requestStream != null)
        requestStream.Close();

    ftpRequest.Abort();

    FtpStatusCode code = ((FtpWebResponse)ex.Response).StatusCode;
    string description = ((FtpWebResponse)ex.Response).StatusDescription;

   _logger.Error("A connection to the ftp server could not be established. Status code: {0}, description: {1} Exception: {2}. Retrying...", code, description, ex.ToString());

那么,场景又是这样的:
1. 正在上传文件,出现System.Net.Sockets.SocketException。
2. 再次尝试,System.Net.Sockets.SocketException再次出现。
3. 在我调用 uploadfile 方法之前,我总是通过尝试列出远程目录来检查远程服务器是否启动以及一切是否正常。从现在开始,通过调用 ftpRequest.GetResponse()(其中 ftpRequest.Method 是 WebRequestMethods.Ftp.ListDirectory)我得到 WebException 状态:未定义,描述:已达到此操作的时间限制。当我重新启动应用程序时,问题消失了。

我找不到其他地方没有正确发布流,也不知道下一步该做什么..

最佳答案

您确定您正确关闭了流并因此正确释放了所有底层资源吗?

如果不是,这可能是导致问题的原因,当您在反复失败后达到极限(例如打开套接字)时。

关于c# - 使用 c# ftp 方法上传文件导致 webexception。程序重启后问题消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/838562/

相关文章:

c# - 在 Windows 窗体中使用 SHA-256 散列文本

ssl - 将文件从 Gentran 服务器上传到 box.com FTPS

c# - 可以将 FTP 与 Amazon S3/Google Drive/OneDrive 一起使用吗?

ftp uploader 或只是一个简单的 uploader

c# - 如何根据地址获取当前时间? C#

c# - 按下按钮后运行事件

c# - 使用 WEB API 的 EntityFramework,更新所有属性

c# - 创建调用方法的表达式树

c++ - FTP 异步操作上的 ERROR_IO_PENDING [Wininet C++]

ios - Xcode - iOS - 只需将文件上传到 FTP 服务器