Listing 1: FTP Communications Source Code

[C#]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.IO;
using System.Net;
using System.Windows.Forms;

namespace FTPFileChecker
{
	public partial class Form1 : Form
	{
		private string downloadFile = "sourcecode.zip"; //The name of the file to download
private string localDir = "c:\\";
private string remoteDir = "//source";	//The directory on the FTP server where downloadFile is located
private string uploadFile = "result.txt"; //The name of the file to create on the FTP server when uploading
		private string targetDir = "//result"; //The name of the upload directory
		private string ftpServer = "ftp://balrog"; //The name of the FTP server
		private string username = "tuser"; //The username for login
		private string password = "CBORD"; //The password for login

		public Form1()
		{
			InitializeComponent();
		}

		private void buttonStart_Click(object sender, EventArgs e)
		{
			timer1.Enabled = true;
buttonStart.Enabled = false;
		}

		private void timer1_Tick(object sender, EventArgs e)
		{
			bool isPresent = false;
			labelLastAttempt.Text = DateTime.Now.ToString();
			try
			{
				isPresent = CheckForFile();

if (isPresent == true)
{
labelLastResponse.Text = "Process Successful";
labelLastTransfer.Text = labelLastAttempt.Text;
}
else
{
labelLastResponse.Text = "File Not Found";
}
			}
			catch (Exception ex)
{
timer1.Enabled = false;
MessageBox.Show(ex.Message);
buttonStart.Enabled = true;
}

		}

		private void buttonStop_Click(object sender, EventArgs e)
		{
			timer1.Enabled = false;
buttonStart.Enabled = true;
		}

		private bool CheckForFile()
		{
			StreamReader reader = null;
Stream downloadResponseStream = null;
Stream uploadRequestStream = null;
FileStream downloadFileStream = null;
FileStream uploadFileStream = null;
			try
			{
//********************************************************************************
//Look for the file on the server by getting a List from the server

//Step 1. Create the FtpWebRequest with the required URI - in this case "ftp://balrog/source"
FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(ftpServer + remoteDir);
//Step 2. Create and set the credentials for login with the username and password
NetworkCredential credentials = new NetworkCredential(username, password);
listRequest.Credentials = credentials;
//Step 3. Specify the command to execute - in this case "ls"
listRequest.Method = WebRequestMethods.Ftp.ListDirectory;
//Step 4. Create the FtpWebResponse to reference the incoming data
FtpWebResponse listResponse = (FtpWebResponse)listRequest.GetResponse();
//Step 5. Initialize the StreamReader with the GetResponseStream that contains the List
reader = new StreamReader(listResponse.GetResponseStream());
string result = reader.ReadToEnd();
textResult.AppendText(textResult.Text + labelLastAttempt.Text + "\r\n" + result + "\r\n");
//*********************************************************************************

//Check if the file is in the listing
if (result.ToUpper().Contains(downloadFile.ToUpper()))
{
//*****************************************************************************
//The file is there so continue to the download phase

//Step 6. Create a new FtpWebRequest, this time with a URI of "ftp://balrog/source/sourcecode.zip"
FtpWebRequest downloadRequest = (FtpWebRequest)WebRequest.Create(ftpServer + remoteDir + "//" +downloadFile);
//Step 7. Set the credentials for the request.  If NetworkCredentials are missing or changed, the request will attempt
//to authenticate the user once again as either anonymous if the credentials are missing or to a new value if the 
//credentials are changed. This will most likely result in an error as the server is not in authentication mode. 
//This is proper operation as FtpWebRequest.KeepAlive is set to "true" by default and thus the previous connection
//is being re-used.
NetworkCredential downloadCredentials = new NetworkCredential(username, password);
downloadRequest.Credentials = downloadCredentials;
//Step 8. Specify that the operation will be a file upload
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;
//Step 9. Create the FtpWebResponse to reference the incoming data
FtpWebResponse downloadResponse = (FtpWebResponse)downloadRequest.GetResponse();
//Step 10. Initialize the Stream with the GetResponseStream that contains the data
downloadResponseStream = downloadResponse.GetResponseStream();
string fileName = downloadFile;
//Step 11. Initialize the FileStream for the local file
downloadFileStream = File.Create(localDir + "\\" + downloadFile);
byte[] downloadBuffer = new byte[1024];
int downloadBytesRead;
//Step 12. Read the date from the Response and write it to the FileStream
while (true)
{
downloadBytesRead = downloadResponseStream.Read(downloadBuffer, 0, downloadBuffer.Length);
if (downloadBytesRead == 0)
break;
downloadFileStream.Write(downloadBuffer, 0, downloadBytesRead);
}
textResult.AppendText("Download complete." + "\r\n");
//***************************************************************************

//***************************************************************************
//The download has finished so proceed to the upload phase

//Step 13. Create a new FtpWebRequest, this time with a URI of "ftp://balrog/result/result.txt"
FtpWebRequest uploadRequest = (FtpWebRequest)WebRequest.Create(ftpServer + targetDir + "//" + uploadFile);
//Step 14. Set the credentials for the request.
NetworkCredential uploadCredentials = new NetworkCredential(username, password);
uploadRequest.Credentials = uploadCredentials;
//Step 15. Specify that the operation will be a file upload
uploadRequest.Method = WebRequestMethods.Ftp.UploadFile;
//Step 16. Set KeepAlive to false to that a "QUIT" command is issued to the server, telling it to close the
//connection after the file transfer.
uploadRequest.KeepAlive = false;
//Step 17. As a habit, Proxy should be set to null during uploads as this operation does not support an Http proxy
uploadRequest.Proxy = null;
//Step 18. Initialize the Stream with the GetRequestStream that will have data written to it
uploadRequestStream = uploadRequest.GetRequestStream();
//Step 19. Initialize the FileStream with the file to upload
uploadFileStream = File.Open(localDir + "\\" + uploadFile, FileMode.Open);
byte[] uploadBuffer = new byte[1024];
int uploadBytesRead;
//Step 20. Read the data from the local file and write it to the Request
while (true)
{
uploadBytesRead = uploadFileStream.Read(uploadBuffer, 0, uploadBuffer.Length);
if (uploadBytesRead == 0)
break;
uploadRequestStream.Write(uploadBuffer, 0, uploadBytesRead);
}

//Step 21. Close the Request as this must be done before before getting the Response.
uploadRequestStream.Close();
//Step 22. Create an FtpWebResponse to hold the server Response. The StatusDescription for the FtpWebResponse
//should tell you that the transfer was complete.
FtpWebResponse uploadResponse = (FtpWebResponse)uploadRequest.GetResponse();
textResult.AppendText("Upload complete." + "\r\n");


//***************************************************************************


return true;
}
else
{
return false;
}

}
		catch (UriFormatException ex)
		{
			throw ex;
		}
		catch (WebException ex)
		{
			throw ex;
		}
            catch (IOException ex)
            {
                	throw ex;
            }
            catch (Exception ex)
		{
			throw ex;
			}
			finally
			{
//Step 23. Cleanup
if (reader != null)
reader.Close();
             if (downloadResponseStream != null)
             downloadResponseStream.Close();
             if (uploadRequestStream != null)
             uploadRequestStream.Close();
             if (downloadFileStream != null)
             downloadFileStream.Close();
             if (uploadFileStream != null)
             uploadFileStream.Close();
			}
		}
		
}
}

Listing 2. FTP Client/Server Communucations for Listing 1

220-server X2 WS_FTP Server 5.0.2.EVAL (430120819)
220-Sun Aug 28 19:43:17 2005
220-29 days remaining on evaluation.
220 server X2 WS_FTP Server 5.0.2.EVAL (430120819)
USER tuser
331 Password required
PASS CBORD
230 user logged in
OPTS utf8 on
501 invalid option
PWD
257 "/users/tuser" is current directory
CWD /users/tuser/
250 CWD successful
TYPE I
200 Type set to IMAGE.
PASV
227 Entering Passive Mode (192,168,0,6,4,50).
NLST Source
150 Opening ASCII data connection for directory listing
226 transfer complete
CWD /users/tuser/Source/
250 CWD successful
TYPE I
200 Type set to IMAGE.
PASV
227Entering Passive Mode (192,168,0,6,4,51).
RETR SourceCode.zip
150 Opening BINARY data connection for SourceCode.zip (921 bytes)
226 transfer complete
CWD /users/tuser/Result/
250 CWD successful
TYPE I
200 Type set to IMAGE.
PASV
227 Entering Passive Mode (192,168,0,6,4,52).
STOR result.txt
150 Opening BINARY data connection for result.txt
226 transfer complete
QUIT
221 Good-Bye