:: Enseignements :: Master :: Master TTT :: 2010-2011 :: Programmation réseau en Java ::
[LOGO]

Projet Transfile


Note préliminaire : ce document n'est pas une version définitive et est susceptible d'évolutions.

Nous souhaitons réaliser un serveur proposant des fichiers en téléchargement ainsi qu'un client permettant de les récupérer. Deux variantes protocolaires sont proposées : la première utilise une connexion TCP pour chaque client téléchargeant tandis que la seconde emploie le protocole UDP en multicast pour plusieurs clients désirant obtenir le même fichier.

Connexion TCP

Serveur de fichiers

Le serveur de fichiers propose en téléchargement les fichiers présents dans un répertoire communiqué et son arborescence. Chaque fichier peut être récupéré en différents tronçons définis par le décalage de son premier octet ainsi que sa taille en octets. Il est nécessaire de pouvoir explorer l'arborescence de fichiers.

Un client souhaitant explorer l'arborescence (lister les enfants d'un répertoire avec des détails tels que leur nom, taille et date de modification) ou télécharger des tronçons doit ouvrir une connexion TCP sur le serveur et lui communiquer des commandes auxquelles il répondra. On proposera un protocole simple sous la forme d'une RFC (en français ou en anglais) pour réaliser ces opérations.

Le serveur doit pouvoir gérer plusieurs connexions avec différents clients simultanément. Il devra maintenir des statistiques de téléchargement qui pourront être obtenues avec une commande spécifique. Elles mentionneront les volumes globaux de données échangées (en émission et réception) ainsi que pour chacun des fichiers servis.

Programme Le serveur sera exécutable via une fonction main implantée dans la classe fr.upemlv.transfile.server.FileServer et acceptera (au moins) les arguments suivants :
  • -p port : port d'attache du serveur
  • -a adresse : adresse d'attache du serveur (par défaut l'adresse joker nulle si celle-ci n'est pas spécifiée)
  • -d racine : répertoire racine de l'arborescence de fichiers servie
  • -r débit : débit maximal servi pour l'ensemble des connexions en octets par seconde (implantation facultative)
Lorsque le serveur reçoit par la JVM un signal de terminaison, celui-ci doit signaler proprement sont extinction aux clients et couper ensuite les connexions. Il écrit ses statistiques dans un fichier server-statistics.

Améliorations De nombreuses améliorations sont imaginables dont par exemple la possibilité de compresser les tronçons à envoyer ou alors de faire jouer également à des clients téléchargeurs un rôle de serveur (partage de fichiers de type BitTorrent).

Client récupérateur de fichiers

Le client implanté devra être compatible avec le protocole défini dans la RFC et utilisé par le serveur. Il devra être capable de télécharger un fichier en plusieurs tronçons et de résister aux coupures de connexion TCP en relançant le téléchargement.

Script Le client utilise un petit langage de script dont les commandes sont communiquées sur l'entrée standard System.in. Ce langage devra comprendre au moins les commandes suivantes :
  • cd répertoire : changement de répertoire courant sur l'arborescence du serveur (avec support des chemins relatifs et absolus, le répertoire racine étant /), le répertoire courant de départ étant la racine
  • ls : affichage du contenu du répertoire courant (un fichier/répertoire par ligne avec ses détails)
  • get fichier : lancement du téléchargement du fichier précisé dans le répertoire courant du serveur
  • get-multicast fichier : lancement du téléchargement en multicast (voir section suivante)
  • status : affichage de tous les fichiers en cours de téléchargement avec leur progression, chaque tâche étant identifiée par un entier
  • kill tâche : tue la tâche de téléchargement dont l'entier est spécifié
Tous les fichiers sont enregistrés sous le répertoire courant de lancement du client mais en respectant l'arborescence du serveur. Par exemple, si l'on télécharge le fichier /java/javadoc/index.html sur le serveur et que le client est lancé sous ~/tmp, le fichier est créé à l'emplacement ~tmp/java/javadoc/index.html (il faudra créer les répertoires intermédiaires si nécessaire). Lorsqu'un téléchargement est tué, les données temporaires ne sont pas effacées et pourront être réutilisées afin d'éviter de retélécharger des tronçons déjà obtenus.

Programme Le client est implanté dans la classe fr.upemlv.transfile.client.FileClient et accepte comme premier argument le nom d'hôte du serveur et pour second son numéro de port.

Connexion multidiffusion UDP

Le mode multidiffusion en UDP permet au serveur d'envoyer le contenu du fichier sous la forme de datagrammes expédiés en un seul exemplaire à un groupe de multicast. Ce mode est intéressant si plusieurs clients souhaitent télécharger simultanément le même fichier. Toutefois il présente certains inconvénients. Le serveur impose une cadence d'envoi pouvant créer des congestions : certains clients en écoute sur le groupe peuvent ne pas recevoir certains paquets.

Le serveur découpe les fichiers à envoyer en tronçons de taille compatible avec un datagramme UDP. Le serveur envoie séquentiellement au groupe de multidiffusion les tronçons numérotés de 0 à n-1 : à l'issue de l'envoi du tronçon n-1, on reprend l'envoi au tronçon 0. Ainsi un client s'étant abonné au groupe et ayant reçu initialement le tronçon i réceptionnera les tronçons i à n-1 puis les tronçons 0 à i-1. Il pourra ensuite se désinscrire du groupe de multidiffusion et constater s'il lui manque ou non des tronçons. Si c'est le cas, il devra redemander l'expédition de ces tronçons en mode TCP.

Le serveur choisit une adresse de groupe de multidiffusion par fichier servi. Un client demande le téléchargement en multidiffusion depuis sa connexion TCP avec le serveur qui lui communique l'adresse du groupe.

Consignes et conseils