I am having problem with ftp, in a windows service. I have scheduled a job to sent files through the ftp. Once in a while i'm having timeout (frequency once a week or maybe once a month), and it continues till i restart my windows service.
System.Net.WebException: The operation has timed out.
I'm handling the exception and in finally i close any opened ftp sessions.
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();
}
}
Any ideas ?
thnx in advance.
Why can't you put this all in a loop? Then, if you have an error, the loop just goes back and tries again.
Also, why have you set the KeepAlive
option to false?
I played around with this for a short while and put it into a class so I could see it better, but did not do any testing on it. My class does the FTP call in a background thread, which is certainly something you'd want to do if you wanted to be able to communicate with this at all.
I certainly give no guarantee that this will work without at least a few glitches!
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);
}
}
来源:https://stackoverflow.com/questions/10044889/consistent-ftp-timeout-in-a-scheduled-windows-service