:: Enseignements :: ESIPE :: E4INFO :: 2013-2014 :: Applications réseaux ::
[LOGO]

Client UDP, respet de l'encodage des caractères


Exercice 1 - Client echo UDP

Écrire un client UDP permettant d'interroger le démon Echo (RFC 862) qui est accessible sur le port 7 d'une machine. Vous pouvez tester ce service en lancant la commande nc -u gaspard 7.
Contrairement à nc, on attend de votre client qu'il soit verbeux et donne de nombreuses informations. Par exemple :
$ java fr.upem.net.udp.EchoUDPClient gaspard 7 "Mon beau message, roi des machines"
socket locale attachée :
à l'adresse 0.0.0.0/0.0.0.0:1044
34 octets émis vers gaspard/193.55.63.81:7
capacité de la zone de stockage : 44
34 octets recus
contenant : Mon beau message, roi des machines
provenant : de gaspard.univ-mlv.fr/193.55.63.81:7

Puisqu'on utilise le protocole Echo, on utilisera l'encodage par défaut de la machine cliente lors de l'envoi et de la réception des messages texte.

Vous pouvez implémenter votre client dans le main.

Si vous n'avez pas accès à la machine gaspard, vous pouvez tester votre client en démarrant un serveur Echo en local. Pour ce faire récupérez le serveur ServerEchoUDP.jar et lancez le sur votre machine avec la commande:
$ java -jar ServerEchoUDP.jar 7777
qui lance le serveur en écoute sur le port 7777 de votre machine. Attention, le jar a été créé avec la version 1.8 de Java.

Exercice 2 - Respecte mon encodage

On souhaite écrire un client UDP permettant d'interroger un serveur de mise en majuscule de chaînes de caractères. Récupérez le serveur ServerUpperCaseUDP.jar et lancez le
$ java -jar ServerUpperCaseUDP.jar 4545 UTF-8

Le serveur décode les paquets reçus comme des chaînes encodées dans son encodage de démarrage et renvoie la chaîne mise en majuscule correspondante encodée dans son encodage de démarrage.

Écrire un client ClientUpperCaseUDP permettant d'interroger le serveur de mise en majuscule lancé sur un port donné d'une machine host. Le client lit les chaînes au clavier et les envoie dans l'encodage pris en paramètre. On attend un fonctionnement du type :
        $ java upem.net.udp.ClientUpperCaseUDP localhost 4545 UTF-8
        Autant arrêter le Java si c'est pour ça!
        AUTANT ARRÊTER LE JAVA SI C'EST POUR ÇA!
        ah l'€
        AH l'€
   

Lancer votre client et le serveur dans deux encodages différents. Par exemple,
$ java -jar ServerUpperCaseUDP 4545 Latin1
$ java upem.net.udp ClientUpperCaseUDP 4545 UTF-8
Que se passe-t-il avec la chaîne "Ah l'€!"

En UDP, les paquets peuvent être perdu. Ce comportement se produit rarement sur un réseau local. Le programme UDPProxy.jar va nous permettre de le simuler sur votre machine. ProxyUDP est un proxy UDP qui va perdre un certain pourcentage des paquets et qui va échanger aléatoirement l'ordre des paquets. Pour l'utiliser, lancez dans un shell différent les trois applications suivantes:
$ java upem.net.udp.ServerUpperCaseUP 7777 UTF-8  
$ java -jar ProxyUDP.jar 5555 localhost 7777 -no-swap 
$ java upem.net.udp.ClientUpperCase localhost 5555 
Dans cet example, ProxyUDP écoute sur le port 5555 et renvoie les paquets vers localhost:7777.

Modifiez votre client de manière à afficher
Le serveur n'a pas répondu
si le serveur n'a pas répondu en moins d'une seconde.

Le problème est que la méthode receive de DatagramChannel est bloquante et qu'il n'est pas possible de lui fournir un timeout. Une solution est de lancer un thread listener qui fera la lecture sur la DatagramChannel et qui communiquera les ByteBuffer recus à votre thread principal au moyen d'une BlockingQueue. Après avoir démarrer votre Thread d'écoute, vous pourrez accéder aux réponses du serveur en utilisant la méthode poll de BlockingQueue qui prend en paramètre un delai de timeout.

Quelles solutions existent pour ignorer les packets ne venant pas du serveur ?

Exercice 3 - Meilleur serveur de mise en masjucules

Pour palier au problème du choix de l'encodage, le serveur ServerBetterUpperCase.jar attend des paquets qui contient une chaîne de caractère avec son encodage. Les paquets ont le format suivant:
  • Un int en BigEndian correspondant à la longueur du nom de l'encodage écrit en ASCII;
  • Le nom de l'encodage en ASCII;
  • La chaîne codée dans l'encodage.
Le serveur renvoie sa réponse dans le même format. Attention l'encodage de la réponse n'est pas nécessairement le même.

Par exemple, la chaîne "élo" dans l'encodage Latin1 correspondra au paquet:
00 00 00 06 4c 61 74 69 6e 31 e9 6c 6f
qui se décompose comme suit:
00 00 00 06  --> int valant 6 (en BigEndian)
4c 61 74 69 6e 31 --> Latin1 en ASCII
e9 6c 6f --> élo en Latin1

Ecrivez un client ClientBetterUpperCaseUDP. On attend un comportement du type:
$ java upem.net.udp.ClientBetterUpperCaseUDP localhost 7778 Latin1
au boulot!
	Received 20 bytes
	Size of charset string : 6
	Charset : IBM437
AU BOULOT!