:: Enseignements :: Master :: Master TTT :: 2012-2013 :: Programmation réseau en Java ::
[LOGO]

Java plus (+)... du tout


Ce sujet est à traiter de manière autonome (aucune communication avec d'autres personnes n'est autorisée, que ce soit localement ou à distance). Seule la consultation des pages sur igm.univ-mlv.fr ainsi que des notes de cours personnelles papier est possible. Toutes les sources produites (fichiers .java) doivent être présentes dans le répertoire EXAM/ à la clôture de la session d'examen.

Exercice 1 - Un petit QCM pour s'échauffer

Les réponses à ce QCM doivent être fournies dans un fichier texte nommé 'qcm.txt' dans le répertoire EXAM. Chaque question peut comporter une ou plusieurs réponses valides. On indiquera le numéro de question, la liste des réponses vraies ainsi qu'une justification.

  1. Nous venons d'appeler la méthode interrupt() d'une thread. Quelles sont les affirmations vraies ?
    1. La thread va être stoppée automatiquement par le système d'exploitation.
    2. Le drapeau d'interruption est mis à vrai.
    3. Dans certains cas InterruptedException peut être levée (lesquels ?).
    4. Dans tous les cas InterruptedException peut être levée (pourquoi ?).
    5. La thread peut mettre si elle le souhaite le drapeau d'interruption à false (comment ?).
  2. Nous disposons d'une machine comportant deux interfaces : localhost sur l'adresse IPv4 127.0.0.1 et eth0 sur 192.168.1.10. Nous programmons un client TCP en Java créeant une socket s'attachant localement sur le port 2013 de localhost. Malheureusement une exception est levée nous indiquant que le port n'est pas libre. Quelles peuvent en être les causes ?
    1. Une autre socket TCP est actuellement attachée sur 127.0.0.1:2013.
    2. Une autre socket TCP est actuellement attachée sur 192.168.1.10:2013.
    3. Une autre socket TCP est actuellement attachée sur 0.0.0.0:2013.
    4. Une socket TCP cliente était attachée sur 127.0.0.1:2013 et le serveur distant est à l'initiative d'une fermeture de connexion (il y a quelques secondes).
    5. Une socket TCP cliente était attachée sur 127.0.0.1:2013, cette socket était à l'initiative d'une fermeture de connexion (il y a quelques secondes).
  3. On dispose de l'API java.{net, io} pour la programmation réseau en Java (avec l'utilisation d'entrées/sorties bloquantes en s'interdisant l'emploi de timeouts). Dans quels cas peut-on se contenter de l'usage d'une thread unique ?
    1. Pour la réalisation d'un serveur UDP communiquant unidirectionnellement avec plusieurs clients simultanément (on ne réalise que des réceptions ou des envois de paquets avec plusieurs clients).
    2. Pour la réalisation d'un serveur UDP communiquant avec un seul client en mode asynchrone (on peut recevoir et envoyer des paquets en même temps avec un seul client).
    3. Pour la réalisation d'un serveur TCP communiquant itérativement avec un seul client à la fois (sans envoi et réception simultanés).
    4. Pour la réalisation d'un serveur TCP communiquant avec plusieurs clients simultanément.

Exercice 2 - Additionneur UDP

On souhaite réaliser un serveur UDP en Java qui aura pour tâche d'additionner les entiers qu'on lui envoie par datagrammes. Le serveur maintient une somme mise à jour en y ajoutant la valeur du paquet reçu ; cette somme mise à jour est renvoyée dans un datagramme au client. La valeur initiale de la somme (lorsqu'aucun paquet n'a encore été reçu) est de 0.

1) Implanter le serveur réalisant cette tâche dans une classe nommée ASCIISumUDPServer. On suppose que les entiers sont communiqués sous forme décimale en caractères ASCII. Il n'y a pas besoin d'implanter le client : le serveur peut être testé en utilisant netcat en tant que client UDP.

Question bonus) [Cette question bonus est à traiter en dernier lorsque l'ensemble du reste du sujet a été abordé] Réimplanter une nouvelle version du serveur avec des entiers communiqués sous forme binaire, en utilisant 4 octets, en commençant par l'octet de poids fort. Par exemple l'entier 2013 serait placé dans un datagrammes comportant les 4 octets suivants, dans cet ordre (en hexadécimal) : 0, 0, 7, DD.
Comme nous sommes gentils, on fournit ici une classe compilée implantant un client permettant de tester le serveur réalisé. Elle est exécutable par la commande java BinintUDPClient adresseServeur portServeur timeout (le timeout est l'attente en millisecondes pour la réception d'un paquet de réponse du serveur).

Exercice 3 - Additionneur TCP

On souhaite maintenant mettre en place un serveur utilisant le protocole TCP réalisant... des additions (quelle originalité ;). Le serveur accueille des clients qui lui communiquent (en caractères ASCII) un entier par ligne. A chaque entier communiqué, le serveur répond par la somme cumulée des entiers proposés jusqu'à présent par le client.

Voici un exemple d'échange (> préfixe un message du client, < une réponse du serveur) :

> 10
< 10
> 1
< 11
> 7
< 18
...


1) Implanter une version itérative du serveur dans une classe nommée IterativeTCPSumServer. Pour cette version, un seul client est géré à la fois. On pourra utiliser netcat en mode client TCP pour tester le serveur.

2) Implanter une version concurrente du serveur dans une classe nommée ConcurrentTCPSumServer. Cette version peut accueillir plusieurs clients simultanément.

3) On désire maintenant maintenir en plus d'une somme locale pour chaque client, une somme globale des entiers communiqués par tous les clients. Créer une nouvelle classe GlobalSumTCPServer qui réalisera cette tâche. À chaque entier communiqué par un client, la somme locale (propre au client) est mise à jour ainsi que la somme globale. Le serveur renvoit à chaque fois sur une ligne la somme locale, une espace puis la somme globale. Expliquer (par un commentaire dans le code) la problématique s'appliquant à la mise à jour de la somme globale dans un contexte concurrent (avec plusieurs clients envoyant simultanément des entiers). Résoudre judicieusement ce problème par la méthode de son choix.

4) Nous implantons maintenant une fonctionnalité permettant à un client d'attendre l'atteinte d'un plancher de somme globale. Par exemple, le client émet la commande (en caractères ASCII sur une ligne) WAIT 2000 pour attendre l'atteinte de 2000 en somme globale. Tant que cette somme n'est pas atteinte, le serveur ne lui retourne rien. Dès que cette somme est atteinte ou dépassée (grâce à l'ajout d'entiers par d'autres clients), on retourne au client la somme globale. Implanter cette fonctionnalité en utilisant le mécanisme d'attente et de signalisation sur moniteur ou verrou (il ne faut bien sûr pas utiliser d'attente active). Ne pas oublier que plusieurs clients peuvent être en attente simultanément avec des planchers différents.