Transfert de fichier par HTTP

Le but du TD est de transférer un fichier par les mécanismes de java. Nous verrons dans les séances suivantes du cours comment ces mécanismes fonctionnent. Les fonctions haut niveau de java permettent d'établir des communications sans connaître ces mécanismes.

Exercice 1. Lire le source de pages web

Le but de l'exercice est d'écrire un programme qui prend en argument un nom de serveur web, son numéro de port et le chemin local d'une URI, se connecte au serveur, récupère la page en question et l'affiche. Ce mécanisme est la base du protocole HTTP utilisé pour surfer sur le web.

Pour récupérer une page web, il suffit de se connecter au port du serveur web (80 par défaut) de la machine et envoyer le texte d'une requête. Par exemple on peut récupérer le source de l'URI http://www.enseignement.polytechnique.fr/informatique ainsi :

triton:~/progs$ telnet www.enseignement.polytechnique.fr 80
GET /informatique HTTP/1.0
Host: www.enseignement.polytechnique.fr

...

(Na pas oublier la ligne blanche.)

La commande telnet se contente d'ouvrir un "socket" vers la machine et le port passés en argument, puis d'envoyer le texte tapé au clavier et d'afficher enfin ce que le serveur distant renvoie. Un socket est une sorte de tuyau de communication par lequel on peut envoyer des caractères et en recevoir. Ce sont les protocoles TCP et IP (qui seront vu dans les séances qui viennent) qui permettent ainsi d'envoyer un flux continu de données (dans les deux sens) entre deux machines de l'Internet sur la base d'envoi de paquets. Disons juste que IP gère l'acheminement des paquets jusqu'à la machine possédant une certaine adresse IP. TCP gère les pertes de paquets et la remise en ordre des paquets pour reconstituer le flux.

La manière de spécifier la requête vers un serveur web est standardisé dans la norme HTTP/1.0. Il suffit de savoir qu'il faut envoyer GET chemin_local_de_l_url HTTP/1.0 suivi d'un caractère fin de ligne ("\n") suivi de Host: nom_du_serveur suivi de deux caractères de fin de ligne.

Il s'agit donc de programmer en java un analogue de la commande telnet. Il suffit pour cela d'ouvrir un socket :

import java.net.* ;

...

      try {
	 Socket sock = new Socket (addr, port) ;
      } catch (UnknownHostException e) {
	 System.out.println ("Serveur inconnu : " + addr.getHostName ()) ;
      } catch (IOException e) {
	 System.out.println ("Erreur de connexion.") ;
      } 

...

Pour ouvrir un socket vers une machine, il faut connaître son adresse IP (4 octets souvent lus comme 4 chiffres entre 0 et 255). Cette adresse est en général déduite d'un nom comme www.enseignement.polytechnique.fr (dont l'adresse IP est 129.104.252.1). (Ce nomage est géré par le protocole DNS.) Pour obtenir l'adresse d'une machine (type InetAddress en java), on utilisera InetAddress.getByName (str)str est une chaîne de caractères contenant le nom.

Comme on peut ouvrir plusieurs sockets vers une machine, un numéro de port permet de les distinguer. Certains numéros de port standards correspondent à des services classique : 80 pour un serveur web, 22 pour ouvrir une connection ssh,... Pour voir la liste des ports prédéfinis sur votre machine sous linux, consultez /etc/services. Les ports supérieurs à 1024 sont en général libres.

sock.getOutputStream () renvoie un OutputStream qui permet d'envoyer des caractères par le socket sock et sock.getInputStream () renvoie un InputStream qui permet de lire les caractères reçus par le socket. Ainsi, on envoie et reçoit des données sur le réseau comme si on écrivait et si on lisait dans des fichiers.

On pourra transformer ces streams en BufferedWriter et BufferedReader pour les manier avec plus de facilités :

      BufferedWriter out = new BufferedWriter (new OutputStreamWriter(sock.getOutputStream ())) ;
      BufferedReader inp = new BufferedReader (new InputStreamReader(sock.getInputStream ())) ;

Ne pas oublier d'utiliser flush() pour vider le buffer d'écriture après avoir écrit la requête.

Documentation java sur le sujet :

Une solution.

Exercice 2. Un faux serveur web

Écrire un serveur web qui interprète le chemin local des uris comme le nom d'un répertoire local et affiche la liste des fichiers du répertoire. On pourra insérer des liens hypertexte pour les fichiers qui sont eux même des répertoires.

Documentation java sur le sujet :

Une solution.

Exercice 3. Serveur web multithread

Répondre à plusieurs requête en même temps. Pour cela, il faut créer un thread par socket de client. Faire des clients très lents pour pouvoir tester votre serveur.


Last modified: Fri Jan 12 08:04:20 CET 2007