Exception on uploading big file by FTP - c#

I'm making a FTP client and trying to upload file to server (~300 MB), but I get following error when nearly 100 MB of the file were transfered:
The underlying connection was closed: An unexpected error occurred on a receive.
Here's my code:
private void UploadFile(string filepath, string filename)
{
try
{
FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create("ftp://" + server + "/" + filename);
//ftp.KeepAlive = false;
//ftp.Timeout = 1000000;
//ftp.UsePassive = true;
//ftp.ReadWriteTimeout = 100000;
Path.GetFileName(filepath);
ftp.Credentials = new NetworkCredential(username, password);
ftp.Method = WebRequestMethods.Ftp.UploadFile;
FileStream stream = File.OpenRead(filepath);
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
stream.Close();
Stream requestStream = ftp.GetRequestStream();
//requestStream.ReadTimeout = 1000000;
//requestStream.WriteTimeout = 1000000;
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();
response.Close();
}
catch (Exception ex) { CreateRunLogFile(ex.Message); }
CreateRunLogFile("Uploading of file " + filepath + " ended.");
}
I try to use,
ftp.KeepAlive = false;
ftp.Timeout = 1000000;
ftp.UsePassive = true;
But it didn't help.

Check the destination firewall settings. If it is a LINUX server running vsFTPd then the server ftp service has FILESIZE and TIMEOUT settings in the config file.
Be sure to restart vsFTPd service after FILESIZE and TIMEOUT settings are adjusted.

Related

Download a file from the FTP server: The remote server returned an error: (425) Can't open data connection

Here is a function I have written to download a file from the FTP server. This works when I call this on the Desktop application or console application. But fails and gives the error message when this is in Windows Service or make a console application called from windows scheduler. I need to get a selected files daily. I am trying to automate instead of running manually every day morning.
private void GetFile(string url, string user, string pwd, string folder, string filename
, string destloc, string destfile)
{
try
{
string RemoteFtpPath = url + folder + "/" + filename;
String DestLoc = destloc + destfile;
String Username = user;
String Password = pwd;
Boolean UseBinary = false; // use true for .zip file or false for a text file
Boolean UsePassive = false;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(RemoteFtpPath);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.KeepAlive = true;
request.UsePassive = UsePassive;
request.UseBinary = UseBinary;
request.Credentials = new NetworkCredential(Username, Password);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
if (File.Exists(DestLoc))
File.Delete(DestLoc);
using (FileStream writer = new FileStream(DestLoc, FileMode.Create))
{
long length = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[2048];
readCount = responseStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
writer.Write(buffer, 0, readCount);
readCount = responseStream.Read(buffer, 0, bufferSize);
}
}
reader.Close();
response.Close();
}
catch (Exception ex)
{
throw ex;
}
}
By changing the properties solved the issue.
request.KeepAlive = false;
request.UsePassive = true;
request.UseBinary = false;

C# download large file from FTP get hung

I have a FTP (Filezila server), and I would like to download a large file on it, using c#.
WebClient client = new WebClient();
client.Credentials = new NetworkCredential(userName, password);
client.DownloadFile(new Uri("ftp://XXX.XXX.XXX.XXX/" + fileName), destinationFileFullPath);
or
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://XXX.XXX.XXX.XXX/" + fileName);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.KeepAlive = true; // I tried both
request.UseBinary = true; // I tried both
request.UsePassive = true;
request.Credentials = new NetworkCredential(userName, password);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
// Writing bytes to local files
using (var outputStream = File.OpenWrite(destinationFileFullPath))
{
byte[] chunk = new byte[2048];
int bytesRead;
do
{
bytesRead = responseStream.Read(chunk, 0, chunk.Length);
outputStream.Write(chunk, 0, bytesRead);
} while (bytesRead > 0);
outputStream.Flush();
}
responseStream.Close();
response.Close();
For small file, it works well, but for large file (by large I mean around ~300MB and more) it works, but at the end of the transfer (I see on filezilla server side that the transfer is a success) for an unknown reason my app just hang on the line
client.DownloadFile(new Uri("ftp://XXX.XXX.XXX.XXX/" + fileName), destinationFileFullPath);
or
bytesRead = responseStream.Read(chunk, 0, chunk.Length);
until I got a timeout exception. If I force the break (pause) I can see that is really stuck on this line. It is like if Filezilla close the connection and C# just wait more to read...
Did you already experienced this issue?
Thanks for your help.

ftpwebrequest.getresponse is throwing 550 access denied

I am trying to figure out how to get this file uploaded to my ftp server in C#. When it calls getResponse() on ftpwebrequest it is throwing an error that says "550 - access denied". I cannot figure out why. I can connect to the server with Filezilla just fine using the same credentials.
Here is my code that does the connection:
private void UploadFileToFTP(HttpPostedFile file, string server, string user, string pass)
{
string uploadUrl = server + file.FileName;
string uploadFileName = Path.GetFileName(file.FileName);
Stream streamObj = file.InputStream;
Byte[] buffer = new Byte[file.ContentLength];
streamObj.Read(buffer, 0, buffer.Length);
streamObj.Close();
streamObj = null;
try
{
SetMethodRequiresCWD();
FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(uploadUrl);
//ftp.Method = WebRequestMethods.Ftp.MakeDirectory;
ftp.Method = WebRequestMethods.Ftp.UploadFile;
ftp.UsePassive = true;
ftp.Credentials = new NetworkCredential(user, pass);
FtpWebResponse CreateForderResponse = (FtpWebResponse)ftp.GetResponse();
if (CreateForderResponse.StatusCode == FtpStatusCode.PathnameCreated)
{
string ftpUrl = string.Format("{0}/{1}", uploadUrl, uploadFileName);
FtpWebRequest requestObj = FtpWebRequest.Create(ftpUrl) as FtpWebRequest;
requestObj.KeepAlive = true;
requestObj.UseBinary = true;
requestObj.Method = WebRequestMethods.Ftp.UploadFile;
requestObj.Credentials = new NetworkCredential(user, pass);
Stream requestStream = requestObj.GetRequestStream();
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Flush();
requestStream.Close();
requestObj = null;
}
}
catch (WebException e)
{
String status = ((FtpWebResponse)e.Response).StatusDescription;
}
}
OK, I tinkered around with this some more after reading through the comments here. I went into my Kaspersky settings and disabled scanning of port 20 and 21. Boom! File is there. Now it is coming across empty for some reason, so I will investigate that or come back for some help here! :)

Uploading file to FTP

I'm having some trouble with uploading a file to a FTP server from C#. My code works well on localhost, but on the live environment it keeps giving me a The operation has timed out. exception.
I use the following code:
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpPath + "/orders.csv");
request.UsePassive = true;
request.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Timeout = -1;
StreamReader sourceStream = new StreamReader(context.Server.MapPath("~/App_Data/orders.csv"));
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
Where ftpPath is the URL of my FTP server: ftp://myserver.com
Does anyone know what I'm doing wrong here? :-)
Thanks in advance.
Some time we need to download, upload file from FTP server. Here is some example to FTP operation.
For this we need to include one namespace and it is. using System.Net
public void DownloadFile(string HostURL, string UserName, string Password, string SourceDirectory, string FileName, string LocalDirectory)
{
if (!File.Exists(LocalDirectory + FileName))
{
try
{
FtpWebRequest requestFileDownload = (FtpWebRequest)WebRequest.Create(HostURL + "/" + SourceDirectory + "/" + FileName);
requestFileDownload.Credentials = new NetworkCredential(UserName, Password);
requestFileDownload.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse responseFileDownload = (FtpWebResponse)requestFileDownload.GetResponse();
Stream responseStream = responseFileDownload.GetResponseStream();
FileStream writeStream = new FileStream(LocalDirectory + FileName, FileMode.Create);
int Length = 2048;
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);
}
responseStream.Close();
writeStream.Close();
requestFileDownload = null;
responseFileDownload = null;
}
catch (Exception ex)
{
throw ex;
}
}
}
This was a permission issue. Seems like the FTP user on my webhotel was restricted (somehow) Tried with another FTP with a user with full permissions and it worked.

Checking if file exist or not on ftp server before downloading it

Before downloading a file from ftp server, I want to check it if exist or not, if not it mu
st throw exception. The code sample works when the file does not exist. However when the file exist, after execution the line; "ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;" it jumps the second catch block and prints "Error: This operation cannot be performed after the request has been submitted." what's the point that i can't see..Thanks for answers.
public void fileDownload(string fileName)
{
stream = new FileStream(filePath + fileName, FileMode.Create);
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpPath + fileName));
ftpRequest.Credentials = new NetworkCredential(userName, password);
ftpRequest.Method = WebRequestMethods.Ftp.GetFileSize;
try
{
response = (FtpWebResponse)ftpRequest.GetResponse();
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
ftpRequest.UseBinary = true;
response = (FtpWebResponse)ftpRequest.GetResponse();
ftpStream = response.GetResponseStream();
cl = response.ContentLength;
bufferSize = 2048;
buffer = new byte[bufferSize];
readCount = ftpStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
stream.Write(buffer, 0, readCount);
readCount = ftpStream.Read(buffer, 0, bufferSize);
}
ftpStream.Close();
stream.Close();
response.Close();
Console.WriteLine("File : " + fileName + " is downloaded from ftp server");
}
catch (WebException ex)
{
FtpWebResponse res = (FtpWebResponse)ex.Response;
if (res.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
{
stream.Close();
File.Delete(filePath + fileName);
Console.WriteLine("File : " + fileName + " does not exists on ftp server");
System.Diagnostics.Debug.WriteLine("Error: " + fileName + " is not available on fpt server");
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Error: " + ex.Message);
}
}
My understanding is that you have to create a new FtpWebRequest for each request you make. So before setting the Method again you'd have to create a new one and set the credentials again. So pretty much that you'd have to repeat the following two lines:
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpPath + fileName));
ftpRequest.Credentials = new NetworkCredential(userName, password);
When you connect to an FTP server you might specify the Uri as "ftp//ftp.domain.com/somedirectory" but this translates to: "ftp://ftp.domain.com/homedirectoryforftp/somedirectory". To be able to define the full root directory use "ftp://ftp.domain.com//somedirectory" which translates to //somedirectory on the machine.

Categories