计划的 Windows 服务中一致的 FTP 超时

Posted

技术标签:

【中文标题】计划的 Windows 服务中一致的 FTP 超时【英文标题】:Consistent FTP timeout in a scheduled windows service 【发布时间】:2012-04-06 14:27:52 【问题描述】:

我在 Windows 服务中遇到了 ftp 问题。我已经安排了一个通过 ftp 发送文件的作业。有时我会超时(频率每周一次或每月一次),它会一直持续到我重新启动 Windows 服务。

System.Net.WebException:操作已超时。

我正在处理异常,最后我关闭了所有打开的 ftp 会话。

try
        
            string uri = String.Format("ftp://0/1/2", server, download, file);
            Uri serverUri = new Uri(uri);
            if (serverUri.Scheme != Uri.UriSchemeFtp)
            
                return;
            
            FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
            reqFTP.Credentials = new NetworkCredential(username, password);
            reqFTP.KeepAlive = false;
            reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
            reqFTP.EnableSsl = false;
            reqFTP.Proxy = null;
            reqFTP.UsePassive = true;
            reqFTP.Timeout = Settings.Default.TimeOut;
            reqFTP.ReadWriteTimeout = Settings.Default.TimeOut;

            response = (FtpWebResponse)reqFTP.GetResponse();
            responseStream = response.GetResponseStream();

            using (FileStream writeStream = new FileStream(path + file, FileMode.Create))
            
                int Length = 10240;
                Byte[] buffer = new Byte[Length];
                int bytesRead = responseStream.Read(buffer, 0, Length);
                while (bytesRead > 0)
                
                    writeStream.Write(buffer, 0, bytesRead);
                    bytesRead = responseStream.Read(buffer, 0, Length);
                
            

            response.Close();
        
        catch (WebException wEx)
        
            LogDatabase.WriteLog("Download File", wEx.ToString(), "Download File");
        
        finally
        
            if (response != null)
            
                response.Close();
            
            if (responseStream != null)
            
                responseStream.Close();
            
        

有什么想法吗?

请提前。

【问题讨论】:

这听起来像是服务器上的问题...也许它正忙于服务其他请求并且已达到最大连接数...您对服务器有任何控制权吗?抛出异常时,你能检查连接的客户端数量吗? 我无权访问服务器,因为我不被允许。但据我所知,它是仅用于这项工作的专用服务器。 你知道为什么吗?我有同样的问题。我也必须重新启动服务。 【参考方案1】:

为什么你不能把这一切都放在一个循环中?然后,如果您有错误,循环将返回并再次尝试。

另外,您为什么将KeepAlive 选项设置为false

我玩了一会儿这个,然后把它放到一个类中,这样我可以更好地看到它,但没有对其进行任何测试。我的班级在后台线程中进行 FTP 调用,如果您希望能够与之通信,这当然是您想要做的事情。

我当然不保证这至少不会出现一些故障!

class FtpRequests 

  private const int BUF_SIZE = 10240;
  private const string PASSWORD = "password";
  private const string USERNAME = "username";
  private const string SERVER = "yourserver.com";
  private string path;

  public FtpRequests() 
    Cancel = false;
    path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
  

  public bool Cancel  get; set; 

  public bool Complete  get; set; 

  public Thread Thread1  get; set; 

  public int Timeout  get; set; 

  public int ReadWriteTimeout  get; set; 

  public void StartFtpDownload(string download, string file) 
    string objString = string.Format("0;1", download, file);
    Thread1 = new Thread(startFtpThread);
    Thread1.Name = string.Format("0 download", file);
    Thread1.IsBackground = true;
    Thread1.Start(objString);
  

  private void startFtpThread(object obj) 
    Complete = false;
    string objString = obj.ToString();
    string[] split = objString.Split(';');
    string download = split[0];
    string file = split[1];
    do 
      try 
        string uri = String.Format("ftp://0/1/2", SERVER, download, file);
        Uri serverUri = new Uri(uri);
        if (serverUri.Scheme != Uri.UriSchemeFtp) 
          Cancel = true;
          return;
        
        FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
        reqFTP.Credentials = new NetworkCredential(USERNAME, PASSWORD);
        reqFTP.KeepAlive = true;
        reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
        reqFTP.EnableSsl = false;
        reqFTP.Proxy = null;
        reqFTP.UsePassive = true;
        reqFTP.Timeout = Timeout;
        reqFTP.ReadWriteTimeout = ReadWriteTimeout;
        using (FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse()) 
          using (Stream responseStream = response.GetResponseStream()) 
            using (FileStream writeStream = new FileStream(path + file, FileMode.Create)) 
              Byte[] buffer = new Byte[BUF_SIZE];
              int bytesRead = responseStream.Read(buffer, 0, BUF_SIZE);
              while (0 < bytesRead) 
                writeStream.Write(buffer, 0, bytesRead);
                bytesRead = responseStream.Read(buffer, 0, BUF_SIZE);
              
            
            responseStream.Close();
          
          response.Close();
          Complete = true;
        
       catch (WebException wEx) 
        LogDatabase.WriteLog("Download File", wEx.ToString(), "Download File");
      
     while (!Cancel && !Complete);
  


【讨论】:

这是一个精心安排的作业,每 10 分钟运行一次整个方法。 ...我的事情是相同的逻辑...

以上是关于计划的 Windows 服务中一致的 FTP 超时的主要内容,如果未能解决你的问题,请参考以下文章

Windows 任务计划程序:由于超时而停止任务错误

FTP上传文件连接超时,本地无问题,服务器上面连接超时?

如何搭建一个ftp服务器呢?

ftp上传时间与ftp服务器中文件显示时间不一致

应用服务计划的 Azure 函数应用超时

用FTP工具FileZilla“连接超时,读取目录失败”