Вы находитесь на странице: 1из 14

Universit Technique de Moldova

RAPPORT
Les travaux pratiques N.4 SI
Le thme Serveur FTP

Elabor par l'tudiant


du groupe FI-121

A. Zghibara

Vrifi par le professeur

M. Cazac

Chiinu-2015

But du travail
Analyser le principe de travail avec un ftp serveur.

Tches du travail
1. Se connecter un serveur ftp avec le client ftp implicite de Windows
2. Dmarrer deux serveurs ftp, un deux le mtre dans le mode passive et transmettre un
fichier dun serveur a lautre.
3. Ecrire notre propre serveur ftp.

Notions thortiques
FTP veut dire File Transfert Protocol ou Protocole de transfert de Fichier.
Cest donc un langage qui va permettre lchange de fichiers entre 2 ordinateurs, et plus
exactement entre un serveur et un client.
On parle alors de :

serveur FTP - un logiciel qui va rpondre aux demandes des clients. Lorsque le serveur
reoit une demande, il vrifie les droits et si le client les droits suffisants, il rpond
cette demande sinon la demande est rejete. Le serveur FTP passe son temps attendre.
Si les demandes ne sont pas nombreuses, les ressources utilises par le serveur FTP sont
quasi-nulles.
client FTP - cest lui qui va tre linitiative de toutes les transactions. Il se connecte au
serveur FTP, effectue les commandes (rcupration ou dpt de fichiers) puis se
dconnecte. Toutes les commandes envoyes et toutes les rponses seront en mode texte.
(cela veut dire quun humain peut facilement saisir les commandes et lire les rponses).
Le protocole FTP nest pas scuris : les mots de passe sont envoys sans cryptage entre
le client FTP et le serveur FTP. (Le protocole FTPS avec S pour secure permet de
crypter les donnes).

Liste des quelques commandes disponibles pour un serveur ftp :


Commande Description
help

Affiche l'ensemble des commandes supportes par le serveur FTP

status

Permet de connatre certains paramtres de la machine cliente

binary

Cette commande vous fait basculer du mode ASCII (envoi de documents textes)
au mode binary (envoi de fichiers en mode binaire, c'est--dire pour les fichiers
non texte, comme des images ou des programmes)

ascii

Bascule du mode binary au mode ascii. Ce mode est le mode par dfaut

type

Permet d'afficher le mode courant de transfert (binary ou ascii)

user

Vous permet de rouvrir une session sur le site FTP en cours avec un nom
d'utilisateur diffrent. Un nouveau mot de passe vous sera alors demand

ls

Permet de lister les fichiers prsents dans le rpertoire courant. La commande "ls
-l" donne des informations supplmentaires sur les fichiers

pwd

Affiche le nom complet du rpertoire courant

cd

Cette commande signifie change directory, elle permet de changer le rpertoire

courant. La commande "cd .." permet d'accder au rpertoire de niveau suprieur


mkdir

Le commande mkdir (sous UNIX, ou md sous systme Microsoft) permet de


crer un rpertoire dans le rpertoire courant. L'utilisation de cette commande est
rserve aux utilisateurs ayant un accs le permettant

rmdir

Le commande rmdir (sous UNIX, ou rd sous systme Microsoft) permet de


supprimer un rpertoire dans le rpertoire courant. L'utilisation de cette
commande est rserve aux utilisateurs ayant un accs le permettant

get

Cette commande permet de rcuprer un fichier prsent sur le serveur


Si la commande est suivie d'un nom de fichier, le fichier distant est
transfr sur la machine locale dans le rpertoire local en cours
Si la commande est suivie de deux noms de fichiers, le fichier distant (le
premier nom) est transfr sur la machine locale dans le rpertoire local
en cours, avec le nom de fichier prcis (le deuxime nom)
Si jamais le nom de fichier contient des espaces il faut veiller le saisir
entre guillemets

put

Cette commande permet d'envoyer un fichier local sur le serveur


Si la commande est suivie d'un nom de fichier, le fichier local est
transfr sur le serveur dans le rpertoire distant en cours
Si la commande est suivie de deux noms de fichiers, le fichier local (le
premier nom) est transfr sur le serveur dans le rpertoire distant en
cours, avec le nom de fichier prcis (le deuxime nom)
Si jamais le nom de fichier contient des espaces il faut veiller le saisir
entre guillemet

open

Ferme la session en cours et ouvre une nouvelle session sur un autre serveur FTP

close

Ferme la session en cours, en laissant le logiciel FTP client actif

bye

Dconnecte le logiciel client du serveur FTP et le met en tat inactif

quit

Dconnecte le logiciel client du serveur FTP et le met en tat inactif

Simple connexion ftp


La plus simple methode de se connecte et dutiliser la commande open IpAddress . Apres cela
on doit introduire le nom dutilisateur et le nom de pass. La deconnexion se fait avec la
commande close ou quit , la derniere va ferme le ftp client.

Mode passif
Fonctionnement du mode actif
1. Le client contacte le serveur sur le port 21 depuis un port aleatoire > 1024. Three-way
handshake classique en TCP
2. Le client envoie la commande PORT qui va specifier au serveur un numero de port a contacter
3. Le Serveur demarre une nouvelle connexion vers le client sur le port specifie par le Client,
avec en port source le port 20. Sen suit un Three way handshake sur ce nouveau port.
Les datas transiteront ensuite par cette connexion.
Fonctionnement du mode passif
1. Le client contacte le serveur sur le port 21 depuis un port aleatoire > 1024. Three-way
handshake classique en TCP
2. Le client envoie la commande PASV pour signifier au serveur quil souhaite une connexion
dite passive.
3. Le serveur Acknowledge la demande du client et lui repond avec le port sur lequel le joindre.
4. Le client demarre une nouvelle connexion vers le serveur sur le port specifie, avec en port
source un nouveau port aleatoire > 1024. Sen suit un Three way handshake sur ce nouveau port.

Exemple

Propre serveur ftp


Code source
using
using
using
using
using
using
using
using

System;
System.Collections.Generic;
System.IO;
System.Linq;
System.Net.Sockets;
System.Text;
System.Threading;
System.Threading.Tasks;

namespace FTPServerConsoleApplication
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Press a key to start the
FtpServer at localhost ...");
Console.ReadKey();
FTPServer Server = new FTPServer();
Server.Start();
Console.WriteLine("FTPServer started at
localhost!\n");
}
}
public delegate void
public delegate void
string IP);
public delegate void
oThread, string IP);
public delegate void

CloseFtp();
Connected(Thread oThread,
Disconnected(Thread
Disconnect(Thread oThread);

class FTPServer
{
private TcpListener FTPCommandListner;
private Socket ClientSocket;
private static int ClientID = 0;
private string ClientIP;
private static int intPort;
private bool bClose = false;
public event
EventHandler<ClientUpdatedEventArgs>
ClientUpdated;
public bool Close
{
set
{
bClose = value;
}
}
public FTPServer()
{
}

public void Dispose()


{
if (FTPCommandListner != null)
{
bClose = true;
Thread.CurrentThread.Join(1000);
if (FTPCommandListner.Pending())
{
FTPCommandListner.Stop();
}
}
}
public Thread Start()
{
Thread startFTPServer = new Thread(new
ThreadStart(Run));
startFTPServer.Start();
return startFTPServer;
}
public void EndSession()
{
if (FTPCommandListner != null)
{
bClose = true;
FTPCommandListner.Stop();
}
}
protected virtual void
OnClientUpdated(ClientUpdatedEventArgs e)
{
if (ClientUpdated != null)
ClientUpdated(this, e);
}
private void SendUpdate(string clientInfo)
{
ClientUpdatedEventArgs nuea = new
ClientUpdatedEventArgs();
nuea.Client = clientInfo;
OnClientUpdated(nuea);
}
private void Run()
{
Thread ClientThread;
FTPCommandListner = new TcpListener(21);
FTPCommandListner.Start();
try
{
while (true)
{
ClientSocket =
FTPCommandListner.AcceptSocket();
ClientThread = new Thread(new
ThreadStart(FTPClientThread));

ClientIP =
ClientSocket.RemoteEndPoint.ToString();
//Raise Event
ClientID++;
ClientThread.Start();
}

}
catch (ThreadInterruptedException)
{
Thread.CurrentThread.Abort();
}
catch (ThreadAbortException)
{
System.Console.WriteLine("Thread killed");
}
}
private void FTPClientThread()
{
int Port = 0;
string user = "";
string PresentDirOnFTP = "/";
string rootDirOnSystem = "C:";
int ClientID = FTPServer.ClientID;
TcpListener FTPDataListner = null;
TcpClient FTPDataClient = null;
Socket ClientSocket = this.ClientSocket;
Socket PassiveClientDataSocket = null;
bool PassiveMode = false;
string serverMsg = "";
string strIP =
ClientSocket.RemoteEndPoint.ToString();
try
{
//Open a Buffered Network Stream for
PI(Protocol Interpreter) IN.
NetworkStream inBuffer = new
NetworkStream(ClientSocket, FileAccess.Read);
//Open a Buffered Network Stream for
PI(Protocol Interpreter) OUT.
NetworkStream outBuffer = new
NetworkStream(ClientSocket, FileAccess.Write);
//Open a Buffered Network Stream for DTP
(Data Transfer Protocol).
NetworkStream nwClientData;
string oldFileName = "";
//Send Greeting to Client
serverMsg = "220 FTP server\r\n";
SendMsg(serverMsg, ref outBuffer);
bool done = false;
while (!done)
{
//break for some time
//other wise with the loop the CPU is
100%
Thread.Sleep(100);
if (!bClose)
{
string clientMsg;
//Poll on the Socket to see do we have
data to read
clientMsg = ReadMsgFromBuffer(ref
ClientSocket, ref inBuffer);
string strSwitchExpression =
clientMsg.Length == 0 ? "" : clientMsg.Substring(0,
4).Trim();
//Parse the FTP Command from Client.
//Tested all the Commands here with
Microsoft Command Prompt FTP .
strSwitchExpression =
strSwitchExpression.ToUpper();
switch (strSwitchExpression)
{
case "USER":
SendUpdate(ClientID + " : " +
clientMsg);
user =
clientMsg.Substring(4).Trim();
SendMsg("331 Password\r\n", ref
outBuffer);
break;
case "PASS":

SendUpdate(ClientID + " : " +


clientMsg);

SendMsg("230 User " + user + "


logged in\r\n", ref outBuffer);
break;
case "XCWD":
goto case "CWD";
case "CDUP":
SendUpdate(ClientID + " : " +
clientMsg);
//Move up one directory
string changeToDir = "..";
SendMsg(ChangeDirectory(rootDirOnSystem, ref
PresentDirOnFTP, changeToDir), ref outBuffer);
break;
case "XCUP":
//Move up one directory
SendUpdate(ClientID + " : " +
clientMsg);
changeToDir = "..";
SendMsg(ChangeDirectory(rootDirOnSystem, ref
PresentDirOnFTP, changeToDir), ref outBuffer);
break;
case "CWD":
SendUpdate(ClientID + " : " +
clientMsg);
changeToDir =
clientMsg.Substring(3).Trim();
SendMsg(ChangeDirectory(rootDirOnSystem, ref
PresentDirOnFTP, changeToDir), ref outBuffer);
break;
case "PORT":
SendUpdate(ClientID + " : " +
clientMsg);
PortData(clientMsg, out Port, out
strIP);
PassiveMode = false;
SendMsg("200 PORT command
successful\r\n", ref outBuffer);
break;
case "PASV":
SendUpdate(ClientID + " : " +
clientMsg);
FTPDataListner = null;
int intPassivePort =
PassiveModePort(ref FTPDataListner);
string strIPAddress =
ClientSocket.RemoteEndPoint.ToString();
//Remove the client Port
strIPAddress =
strIPAddress.IndexOf(":") > 0 ?
strIPAddress.Substring(0, strIPAddress.IndexOf(":")) :
strIPAddress;
strIPAddress =
strIPAddress.Replace(Convert.ToChar("."),
Convert.ToChar(","));
strIPAddress = strIPAddress + ","
+ intPassivePort / 256 + "," + (intPassivePort % 256);
SendMsg("227 Entering Passive
Mode (" + strIPAddress + ")\r\n", ref outBuffer);
PassiveClientDataSocket =
PassiveClientSocket(ref FTPDataListner,
intPassivePort);
if (PassiveClientDataSocket ==
null)
{
SendMsg("425 Error in Passive
Mode connection\r\n", ref outBuffer);
}
PassiveMode = true;
break;
case "TYPE":
//Emulate the TYPE Command
SendUpdate(ClientID + " : " +
clientMsg);
SendMsg("200 type set\r\n", ref
outBuffer);
break;
case "RETR":

//Send the requested file to


Client.

//Raise event for the Form1


Window to register the request
SendUpdate(ClientID + " : " +
clientMsg);
SendMsg("150 Binary data
connection\r\n", ref outBuffer);
clientMsg =
clientMsg.Substring(4).Trim();
//Open the requested file for
Transfer.
clientMsg =
clientMsg.Replace(Convert.ToChar("\\"), '/');
clientMsg =
(clientMsg.Substring(0, 1) == "/" ?
clientMsg.Substring(1) : clientMsg);
string strPath = rootDirOnSystem
+ PresentDirOnFTP;
strPath =
(strPath.Substring(strPath.Length - 1, 1) == "/" ?
strPath : strPath + "/");
strPath += clientMsg;
nwClientData =
Mode(PassiveMode, ref FTPDataClient, ref
PassiveClientDataSocket, strIP, Port);
if (SendFile(strPath, ref
nwClientData))
{
SendMsg("226 transfer
complete\r\n", ref outBuffer);
}
else
{
SendMsg("550 file not found,
or no access.\r\n", ref outBuffer);
}
PassiveMode = false;
break;
case "STOR":
//Create File on the FTP Server
SendMsg("150 Binary data
connection\r\n", ref outBuffer);
SendUpdate(ClientID + " : " +
clientMsg);
clientMsg =
clientMsg.Substring(4).Trim();
nwClientData =
Mode(PassiveMode, ref FTPDataClient, ref
PassiveClientDataSocket, strIP, Port);
//Open the requested file for
Transfer.
clientMsg =
clientMsg.Replace(Convert.ToChar("\\"), '/');
clientMsg =
(clientMsg.Substring(0, 1) == "/" ?
clientMsg.Substring(1) : clientMsg);
strPath = rootDirOnSystem +
PresentDirOnFTP;
strPath =
(strPath.Substring(strPath.Length - 1, 1) == "/" ?
strPath : strPath + "/");
strPath += clientMsg;
//Open the requested file for
Transfer.
if (CreateFile(strPath, ref
nwClientData))
{
SendMsg("226 transfer
complete \r\n", ref outBuffer);
}
else
{
SendMsg("550 file not found,
or no access.\r\n", ref outBuffer);
}
PassiveMode = false;
break;
case "NLST":
goto case "LIST";
case "LIST":
SendUpdate(ClientID + " : " +
clientMsg);

SendMsg("150 code --> ASCII


data\r\n", ref outBuffer);
nwClientData =
Mode(PassiveMode, ref FTPDataClient, ref
PassiveClientDataSocket, strIP, Port);
ListDirectory(rootDirOnSystem,
PresentDirOnFTP, ref nwClientData);
//Close the socket to signal the
End of Data Transfer
if (!PassiveMode)
{
nwClientData.Close();
}
else
{
if (PassiveClientDataSocket !=
null)
{
nwClientData.Close();
}
}
SendMsg("226 Transfer
complete.\r\n", ref outBuffer);
break;
case "XPWD":
goto case "PWD";
case "PWD":
SendUpdate(ClientID + " : " +
clientMsg);
SendMsg("257 " + "\"" +
PresentDirOnFTP + "\"" + " is current directory \r\n",
ref outBuffer);
break;
case "DELE":
//Delete the file from the Server
and reply back.
SendUpdate(ClientID + " : " +
clientMsg);
clientMsg =
clientMsg.Substring(4).Trim();
SendMsg(DeleteFileForServer(rootDirOnSystem,
PresentDirOnFTP, clientMsg), ref outBuffer);
break;
case "XRMD":
goto case "RMD";
case "RMD":
//Remove Directory
SendUpdate(ClientID + " : " +
clientMsg);
clientMsg =
clientMsg.Substring(4).Trim();
SendMsg(RemoveDirectory(rootDirOnSystem,
PresentDirOnFTP, clientMsg), ref outBuffer);
break;
case "XMKD":
goto case "MKD";
case "MKD":
//Make Directory
SendUpdate(ClientID + " : " +
clientMsg);
clientMsg =
clientMsg.Substring(4).Trim();
SendMsg(CreateDirectory(rootDirOnSystem,
PresentDirOnFTP, clientMsg), ref outBuffer);
break;
case "NOOP":
SendMsg("200 NOOP command
executed.\r\n", ref outBuffer);
break;
case "HELP":
SendMsg("Ftp Server created at
UTM\r\n", ref outBuffer);
//214 list of supported command
break;
case "ABOR":
goto case "QUIT";
case "QUIT":
SendUpdate(ClientID + " : " +
clientMsg);

if (PassiveClientDataSocket !=
null)

done = true;
break;
case "RNFR":
//Rename File
SendUpdate(ClientID + " : " +

oldFileName =
FilePath(rootDirOnSystem, PresentDirOnFTP,
clientMsg.Substring(4).Trim());
if (File.Exists(oldFileName))
{
SendMsg("350 Requested file
action pending further info \r\n", ref outBuffer);
}
else
{
SendMsg("550 Requested file
not found\r\n", ref outBuffer);
oldFileName = "";
}
break;
case "RNTO":
SendUpdate(ClientID + " : " +
clientMsg);
if (oldFileName != "")
{
string strNewFile =
FilePath(rootDirOnSystem, PresentDirOnFTP,
clientMsg.Substring(4).Trim());
File.Copy(oldFileName,
strNewFile);
File.Delete(oldFileName);
}
SendMsg("250 Requested file
action completed. \r\n", ref outBuffer);
break;
case "REST":
SendMsg("350 Requested file
action pending further info \r\n", ref outBuffer);
break;
case "": //We have recieved blank
break;
default: //We Don't understand the
Command
clientMsg);

SendUpdate(ClientID + " : " + e.ToString());


}
//At the End make the flag true;
bClose = false;

PassiveClientDataSocket.Close();
}
if (FTPDataClient != null)
{
FTPDataClient.Close();
}
SendMsg("257 code -->" + "\"" +
PresentDirOnFTP + "\"" + " is current directory " + "
and 221 code --> GOOD BYE\r\n", ref outBuffer);

clientMsg);

SendUpdate(ClientID + " : " +

SendMsg("500 Command not


understood\r\n", ref outBuffer);
break;
}
}
else
{
done = true;
SendMsg("221 Connection forcefull
closed. \r\n", ref outBuffer);
outBuffer.Close();
inBuffer.Close();
}
}
ClientSocket.Close();
}
catch (ThreadInterruptedException)
{
bClose = false;
Thread.CurrentThread.Abort();
}
catch (Exception e)

}
private string FilePath(string rootDirOnServer,
string PresentDirOfFTP, string fileName)
{
Thread oThread = Thread.CurrentThread;
lock (oThread)
{
//Change to proper file format..
fileName = fileName.Trim();
rootDirOnServer = rootDirOnServer.Trim();
PresentDirOfFTP = PresentDirOfFTP.Trim();
rootDirOnServer =
rootDirOnServer.Replace(Convert.ToChar("\\"), '/');
PresentDirOfFTP =
PresentDirOfFTP.Replace(Convert.ToChar("\\"), '/');
fileName =
fileName.Replace(Convert.ToChar("\\"), '/');
//Remove the PresentDirOfFTP from
filename
string root = "";
string changeTo = "";
if (fileName.LastIndexOf("/") > 0)
{
fileName = fileName.Substring(0, 1) !=
"/" ? "/" + fileName : fileName;
root = rootDirOnServer + fileName;
changeTo = fileName;
}
else
{
root = rootDirOnServer +
PresentDirOfFTP;
if (root.Substring(root.Length - 1, 1) !=
"/")
{
root += "/";
}
if (fileName.Substring(0, 1) == "/")
{
fileName =
fileName.Substring(1).Trim();
}
//Error Correction Logic
//??
string tmpRoot = root + fileName;
try
{
if (Directory.Exists(tmpRoot))
{
//Change to this Directory
root = tmpRoot;
}
else
{
//Not found try with System Root
tmpRoot = fileName.Substring(0, 1)
!= "/" ? "/" + fileName : fileName;
tmpRoot = rootDirOnServer +
tmpRoot;
if (Directory.Exists(tmpRoot))
{
root = tmpRoot;
}
else
{
//Directory doen't exist...
root += fileName;
}
}

}
catch (Exception)
{
//No Directory Exist
root += fileName;
}

return root;
}

private string RenameTheFile(string fileName)


{
Thread oThread = Thread.CurrentThread;
lock (oThread)
{
try
{
if (File.Exists(fileName))
{

return "550 Directory already


exists!\r\n";

}
}
catch (Exception)
{
}
return null;

}
private string RemoveDirectory(string
rootDirOnServer, string PresentDirOfFTP, string
fileName)
{
Thread oThread = Thread.CurrentThread;
lock (oThread)
{
rootDirOnServer =
rootDirOnServer.Replace(Convert.ToChar("\\"), '/');
PresentDirOfFTP =
PresentDirOfFTP.Replace(Convert.ToChar("\\"), '/');
fileName =
fileName.Replace(Convert.ToChar("\\"), '/');
string root = "";
root = rootDirOnServer + PresentDirOfFTP;
if (root.Substring(root.Length - 1, 1) != "/")
{
root += "/";
}
if (fileName.Substring(0, 1) == "/")
{
fileName = fileName.Substring(1).Trim();
}
root += fileName;
try
{
if (Directory.Exists(root))
{
Directory.Delete(root, true);
return "250 Directory deleted.\r\n";
}
else
{
return "550 Directory not found, or no
access.\r\n";
}
}
catch (Exception)
{
return "550 Command can't be
executed.\r\n";
}
}
}
private string CreateDirectory(string
rootDirOnServer, string PresentDirOfFTP, string
fileName)
{
Thread oThread = Thread.CurrentThread;
lock (oThread)
{
//Change to proper file format..
string root = FilePath(rootDirOnServer,
PresentDirOfFTP, fileName);
try
{
if (Directory.Exists(root))
{

}
else
{
Directory.CreateDirectory(root);
return "257 Directory Created.\r\n";
}

}
catch (Exception e)
{
SendUpdate(ClientID + " : " +
e.ToString());
return "550 Command can't
executed.\r\n";
}
}
}

private string ChangeDirectory(string


rootDirOnServer, ref string PresentDirOfFTP, string
fileName)
{
Thread oThread = Thread.CurrentThread;
lock (oThread)
{
bool bUp = false;
string root = FilePath(rootDirOnServer,
PresentDirOfFTP, fileName);
if (fileName.Length >= 2)
{
if (fileName.Substring(0, 2) == ".." ||
fileName.IndexOf("..") > 0)
{
//change to parent dir..
if (PresentDirOfFTP.Length > 1)
{
string temp = "";
string[] updir = fileName.Split(new
char[] { '/' });
int iDirectoryUp = updir.Length;
int iStart = PresentDirOfFTP.Length;
for (int i = 0; i < iDirectoryUp; i++)
{
int iPosUnder =
PresentDirOfFTP.LastIndexOf("/", iStart);
temp =
PresentDirOfFTP.Substring(0, iPosUnder);
iStart = iPosUnder - 1;
if (iStart <= 0)
{
break;
}
}
fileName = temp;
}
else if
(PresentDirOfFTP.LastIndexOf("/") == 0)
{
//We are at root
fileName = "";
}
root = rootDirOnServer + fileName;
bUp = true;
}
}
try
{
if (Directory.Exists(root))
{
if
(PresentDirOfFTP.Substring(PresentDirOfFTP.Length 1, 1) == "/")
{
PresentDirOfFTP =
PresentDirOfFTP.Substring(0, PresentDirOfFTP.Length
- 1);
}
if (bUp)
{
PresentDirOfFTP = root.Remove(0,
rootDirOnServer.Length);
if (PresentDirOfFTP == "")

{
PresentDirOfFTP = "/";

}
}
else
{
PresentDirOfFTP = root.Remove(0,
rootDirOnServer.Length);
}
return "250 CWD command
succesful\r\n";
}
else
{
SendUpdate(ClientID + " : " +
"Directory not found, or no access." + fileName);
return "550 Directory not found, or no
access.\r\n";
}
}
catch (IOException e)
{
SendUpdate(ClientID + " : " +
e.ToString());
return "550 Directory not found, or no
access.\r\n";
}
}
}
private string DeleteFileForServer(string
rootDirOnServer, string PresentDirOfFTP, string
fileName)
{
//check for seperator
Thread oThread = Thread.CurrentThread;
lock (oThread)
{
string root = FilePath(rootDirOnServer,
PresentDirOfFTP, fileName);
try
{
FileInfo oFile = new FileInfo(root);
if (oFile.FullName != "")
{
oFile.Delete();
return "250 delete command
successful\r\n";
}
}
catch (FileNotFoundException e)
{
SendUpdate(ClientID + " : " +
e.ToString());
return "550 file not found, or no
access.\r\n";
}
catch (IOException e)
{
SendUpdate(ClientID + " : " +
e.ToString());
return "550 file not found, or no
access.\r\n";
}
SendUpdate(ClientID + " : " + "Error in
Deleteing file " + fileName);
return "550 file not found, or no
access.\r\n";
}
}
private bool ListDirectory(string
rootDirOnSystem, string PresentDirOnFTP, ref
NetworkStream nw)
{
//Open the Directory
string strPath = rootDirOnSystem +
PresentDirOnFTP;
string strFileNameTemp = "";
DirectoryInfo oDir = new
DirectoryInfo(strPath);
FileInfo[] oFiles = oDir.GetFiles();

DirectoryInfo[] oDirectories =
oDir.GetDirectories();
try
{
foreach (FileInfo oFile in oFiles)
{
string strFile;
strFile = "";
try
{
if
(oFile.Name.Substring(oFile.Name.Length - 4) !=
".SYS")
{
strFileNameTemp =
oFile.Name.Replace(Convert.ToChar("\\"), '/');
strFile += strFileNameTemp.Trim()
+ "\r\n";
byte[] Buffer =
Encoding.ASCII.GetBytes(strFile);
try
{
if (nw.CanWrite)
{
nw.Write(Buffer, 0,
Buffer.Length);
}
}
catch (Exception)
{
}

}
catch (Exception)
{
//Some Error in Reading the Files
Information

}
}
foreach (DirectoryInfo od in oDirectories)
{
string strDirectory;
strDirectory = "";
strFileNameTemp =
od.Name.Replace(Convert.ToChar("\\"), '/');
strDirectory += strFileNameTemp.Trim()
+ "\r\n";
byte[] Buffer =
Encoding.ASCII.GetBytes(strDirectory);
try
{
if (nw.CanWrite)
{
nw.Write(Buffer, 0, Buffer.Length);
}
}
catch (Exception)
{
}
// }

}
}
catch (IOException e)
{
SendUpdate(ClientID + " : " + e.ToString());
return false;
}
return true;

private NetworkStream Mode(bool PassiveMode,


ref TcpClient client, ref Socket clientSocket, string
strIP, int Port)
{
Thread oThread = Thread.CurrentThread;
NetworkStream nw = null;
lock (oThread)
{
if (PassiveMode)
{
//Socket is Opened

if (clientSocket != null)
{
nw = new
NetworkStream(clientSocket, FileAccess.ReadWrite);
}
}
else
{
//Client Need to be Connected
client = new TcpClient(strIP, Port);
nw = client.GetStream();
}
}
return nw;
}
private string ReadMsgFromBuffer(ref Socket
clientSocket, ref NetworkStream inBuffer)
{
string clientMsg = "";
StringBuilder clientTmp = new
StringBuilder();
byte[] buffer = new Byte[1024];
int iBytes = 0;
Thread oThread = Thread.CurrentThread;
lock (oThread)
{
string tmp = "";
if (clientSocket.Available > 0)
{
while (clientSocket.Available > 0)
{
iBytes = inBuffer.Read(buffer, 0,
buffer.Length);
tmp =
Encoding.ASCII.GetString(buffer, 0, iBytes);
clientTmp.Append(tmp);
}
}
clientMsg = clientTmp.ToString();
}
return clientMsg;
}
private void SendMsg(string msg, ref
NetworkStream outBuffer)
{
Thread oThread = Thread.CurrentThread;
lock (oThread)
{
byte[] buffer;
buffer = Encoding.ASCII.GetBytes(msg);
outBuffer.Write(buffer, 0, buffer.Length);
}
}
private bool SendFile(string strpath, ref
NetworkStream nw)
{
Thread oThread = Thread.CurrentThread;
try
{
lock (oThread)
{
StreamReader outFile = new
StreamReader(strpath);
char[] buff = new Char[1024];
int amount;
while ((amount = outFile.Read(buff, 0,
1024)) != 0)

byte[] buffer =
Encoding.ASCII.GetBytes(buff);
nw.Write(buffer, 0, amount);
}
}
}
catch (Exception e)
{
SendUpdate(ClientID + " : " + e.ToString());
nw.Close();

return false;
}
nw.Close();
return true;

private bool CreateFile(string strpath, ref


NetworkStream nw)
{
Thread oThread = Thread.CurrentThread;
lock (oThread)
{
try
{
StreamWriter inFile = new
StreamWriter(strpath);
byte[] buffer = new Byte[128];
int iBytes = 1;
while (iBytes != 0)
{
iBytes = nw.Read(buffer, 0,
buffer.Length);
char[] buff =
Encoding.ASCII.GetChars(buffer);
inFile.Write(buff, 0, buff.Length);
}
inFile.Close();
}
catch (Exception)
{
nw.Close();
return false;
}
nw.Close();
return true;
}
}
private int PassiveModePort(ref TcpListener
clientDataListner)
{
Thread oThread = Thread.CurrentThread;
lock (oThread)
{
int intPort = 0;
bool done = true;
while (done)
{
intPort = Port();
try
{
if (clientDataListner != null)
{
clientDataListner.Stop();
}
clientDataListner = new
TcpListener(intPort);
clientDataListner.Start();
//This Port is free
done = false;
}
catch (Exception)
{
//done=false;
}
}
return intPort;
}
}
private Socket PassiveClientSocket(ref
TcpListener clientDataListner, int intPort)
{
Thread oThread = Thread.CurrentThread;
lock (oThread)
{
try
{
if (clientDataListner.LocalEndpoint ==
null)
{
Socket s = null;
try

{
s=
clientDataListner.AcceptSocket();
}
catch (Exception)
{
}
return s;
}
else
{
Socket s =
clientDataListner.AcceptSocket();
return s;
}
}
catch (Exception e)
{
SendUpdate(ClientID + " : " +
e.StackTrace);
}
return null;
}
}
//Get Free Port Numeber from Operating System
private int Port()
{
if (intPort == 0)
{
intPort = 1100;
}
else
{
intPort++;
}
return intPort;
}
private void PortData(string clientMsg, out int
Port, out string strIP)
{
Thread oThread = Thread.CurrentThread;
lock (oThread)
{
Port = 0;
//Remove the FTP Command
clientMsg = clientMsg.Remove(0, 5);

//Remove the last two character


clientMsg = clientMsg.Substring(0,
clientMsg.Length - 2);
int iLen = clientMsg.Length;
int iCounter = 0;
StringBuilder IP = new StringBuilder();
string clientPort = "";
for (int i = 0; i < iLen; i++)
{
if (clientMsg.Substring(i, 1) == ",")
{
iCounter++;
if (iCounter == 4)
{
clientPort = clientMsg.Substring(i +
1);
break;
}
else
{
IP.Append(clientMsg.Substring(i,
1));
}
}
else
{
IP.Append(clientMsg.Substring(i, 1));
}
}
//IP of the Client
strIP = IP.ToString().Replace(',', '.');
string[] strPort = clientPort.Split(new Char[]
{ ',' });
if (strPort.Length > 0)
{
Port = (int)
(Convert.ToDecimal(strPort[0]) * 256 +
Convert.ToDecimal(strPort[1]));
}
}
}
}
public class ClientUpdatedEventArgs : EventArgs
{
public string Client { get; set; }
}
}

Exemple dutilisation

Conclusion
Daprs ce travail pratique jai me familiarise avec les principes de travail dun ftp serveur. La
chose la plus complexe est de faire ton propre ftp serveur en respectant toutes les normes
dclaratives et fonctionnelles. Aussi le mode passive reste une partie importante du
fonctionnement car permet de transfrer de fichiers dune place une autre sans beaucoup de
problmes.