TP Noté 2017 : mini client FTP

Dans ce sujet, nous vous demandons de réaliser un mini client FTP permettant de télécharger un fichier d'un dépôt d'un serveur FTP. La version finale pourra lancer plusieurs téléchargements en parallèle. Les échanges réseau et les écritures sur fichier doivent être écrits en utilisant la bibliothèque Java NIO.

Importez l'archive Eclipse. Renommez le projet CSC4509-TP-Note avec le nom tpnote-VotreNom. Créez aussi dans cette arborescence du projet un fichier readme.txt dans lequel vous mettrez vos notes.

Le barème est donné à titre d'indication.

En fin de TP :

  1. si ce n'est pas déjà fait, créez un fichier readme.txt dans lequel vous mettez vos notes à destination des correcteurs ;
  2. exportez votre projet Eclipse sous la forme d'une archive :
  3. déposez le fichier sur moodle comme devoir ;
  4. vérifiez avec l'enseignant présent dans la salle que le fichier téléchargé est correct.

1. Présentation du sujet

Objectif : écrire des classes qui déroulent la partie du protocole FTP qui permet de télécharger un fichier.

Un client et un serveur FTP contiennent chacun deux composants distincts :

  1. un premier composant appelé Protcol Interpreter (PI) échange avec le PI distant les demandes et les réponses du protocole. Ces échanges sont tous faits à l'aide d'une unique ligne de texte (une chaîne de caractères ASCII se terminant par le caractère « \n »). Une demande = une seule ligne. Tous ces échanges se font à travers la connexion qu'a établie le client avec le serveur lors de son lancement ;
  2. le second composant appelé Data Transfer Process (DTP) échange les informations qu'il n'est pas possible de faire passer sur une seule ligne. Par exemple, cela peut être le résultat la commande « dir », ou bien le contenu du fichier à échanger. Un nouveau DTP est créé de chaque côté pour chaque nouvel échange. Une connexion est établie entre ces deux DTP et les données sont transmises à travers cette connexion.

Voici deux exemples de scénarios utilisés dans notre application :

  1. un client (déjà connecté au serveur) change le répertoire courant du serveur. Voici les différentes étapes du protocole :
  2. un client (déjà connecté au serveur) télécharge un fichier du répertoire courant du serveur. Voici les différentes étapes du protocole :
protocole pour le téléchargement d'un fichier
Fig 1: protocole pour le téléchargement d'un fichier

Tous les messages envoyés par le PI du serveur commencent par un code de 3 chiffres. Le premier de ces chiffres indique le succès ou l'échec de la demande faite par le client. Si le code commence par 1, 2 ou 3, la demande a réussi (éventuellement partiellement). Si le code commence par 4 ou 5, la demande a échoué. Vous devrez tenir compte de ce code de retour à chaque étape.

2. Connexion du PI du client FTP et premiers échanges (6 points)

Dans cette partie, vous commencez à compléter la classe FtpProtocolInterpreter. En guise de serveur de test, vous utilisez l'adresse ftp.int-evry.fr (port 21), avec comme identifiant « anonymous » et comme mot de passe, votre login DISI (le login et surtout pas le mot de passe).

Le PI du client FTP peut être dans les trois états différents listés dans l'énumération FtpPIStatus :

Il faut veiller à maintenir l'état du PI du client FTP (attribut status) de façon à ce qu'il soit cohérent avec son historique.

2.1 Connexion au serveur (2 points)

Écrivez la méthode connectTo(String servHostname, int port) qui permet à un client TCP de se connecter au serveur tournant sur le machine servHostname et le port port.

Le protocole de connexion se fait en 2 étapes:

Notez que pour tout ce TP, vous pouvez considérer que les échanges entre les 2 PI ne sont jamais morcelés. Donc une seule lecture suffit à lire une réponse du PI du serveur. Vous ne pourrez pas faire cette supposition pour les échanges entre les DTP.

Testez votre méthode en construisant un FtpProtocolInterpreter dans la classe d'application MiniFtp et le connectant au serveur de test.

2.2 Identification (3 points)

Écrivez la méthode logToServer(String user, String pass) qui, une fois la connexion établie, déroule le protocole d'identification. Il se déroule en 4 étapes :

Testez votre méthode dans la classe d'application MiniFtp en vous identifiant sur le serveur de test.

2.3 Commande CWD (1 point)

Écrivez la méthode cwdCmd(String directory) qui, une fois l'identification réussie, permet de demander au serveur de changer son répertoire courant. Le protocole se déroule en 2 étapes :

Testez votre méthode dans la classe d'application MiniFtp en demandant au serveur d'aller dans le répertoire /pub/rfc

3. Écriture du DTP du client (4 points)

Dans cette partie, vous écrivez la classe FtpDataTransferProcess. Le DTP du client se connecte à l'adresse TCP/IP donnée à sa construction, et reçoit les données du DTP du serveur lorsque nous utilisons la méthode receiveData(). Une fois les données reçues, le DTP ferme la connexion.

Toutes les lectures et écritures sont faites en utilisant les canaux de JAVA NIO.

4. Téléchargement d'un fichier (5 points)

Dans cette partie, vous écrivez la méthode retrCmd(String fileName). Cette méthode déroule le protocole de récupération d'un fichier du répertoire courant du serveur (voir la figure 1 dans la section « 1. Présentation du sujet ») :

Dans le paquetage util, vous trouvez la classe PasvResponse. Elle vous fournit les méthodes qui analysent la réponse de la commande PASV et donnent les adresses et ports TCP/IP correspondants.

Testez votre méthode dans la classe d'application MiniFtp en demandant au serveur d'envoyer le fichier rfc959.txt du répertoire /pub/rfc. En cas de réussite, le fichier arrive dans le répertoire workspace/tpnote-VotreNom.

5. Multiconnexion, multitéléchargement (5 points)

Dans cette partie, le PI du client FTP est modifié pour que nous puissions en lancer plusieurs en même temps dans des threads différents.

Modifiez la classe FtpProtocolInterpreter pour qu'elle puisse être lancée dans un nouveau thread.

La méthode run() doit:

Il faut donc aussi écrire un nouveau constructeur à cette classe pour initialiser toutes les informations nécessaires à cette méthode.

Testez la nouvelle version de la classe en créant dans la classe d'application quatre threads afin de (tenter de) télécharger les quatre fichiers /pub/rfc/rfc114.txt, /pub/rfc/rfc454.txt, /pub/rfc/nexistepas et /pub/rfc/rfc949.txt.