Examen 2h sur machine

Consignes

L'examen est composé de trois exercices indépendants qui peuvent être traités dans l'ordre que vous voulez. Les exercices 2 et 3 utilisent le même protocole. Il faut donc lire la présentation du protocole au début de l'exercice 2 pour pouvoir faire l'exercice 3.


Rappel : si ce n'est pas déjà le cas, vous devez configurer le workspace d'Eclipse (File > Switch WorkSpace) pour qu'il corresponde au répertoire EXAM présent dans le home de votre session de TP noté.

Vérifiez bien que tous vos fichiers sont dans le répertoire EXAM. Tout ce qui n'est pas dans ce répertoire est perdu quand vous vous déconnectez (ou en cas de panne).

Vous avez le droit de consulter les transparents du cours.

La Java doc est ici.

Client TCP UGEPT

Toutes les classes demandées dans cet exercice doivent se trouver dans le package fr.uge.net.tcp.exam2024.ex1

Dans cet exercice, vous devez écrire un client TCP en mode bloquant pour le protocole UGEPT décrit ci-dessous. Ce protocole permet d'interroger une IA de pointe développée au LIGM.

Protocole UGEPT

Le client envoie un prompt qui est une chaîne de caractères au format suivant:

  • un INT en BigEndian donnant le nombre d'octets de la chaîne encodée en UTF-8;
  • les octets de la chaîne encodée en UTF-8.

Le serveur répond avec une suite de chaînes de caractères dans un format différent de celui du client. La fin de cette suite est signalée par la chaîne STOP. Dans la réponse du serveur, les chaînes de caractères sont envoyées au format suivant:

  • les octets de la chaîne de caractères encodée en UFT8 (il ne peut pas y avoir plus de 1023 octets),
  • un octet valant 10.

Après sa réponse, le serveur ne ferme pas la connexion, de sorte que le client puisse faire une autre requête. C'est le client qui décide de fermer la connexion lorsqu'il n'a plus de requête à faire.

Par exemple, si le client veut envoyer le prompt "Du java ?", il enverra les octets suivants:

00 00 00 09 44 75 20 6A 61 76 61 20 3F
qui se décomposent comme suit:
00 00 00 09 \\ un INT en BigEndian valant 9
44 75 20 6A 61 76 61 20 3F \\ les octets de la chaîne "Du java ?" en UTF-8

Supposons que le serveur veut répondre avec les deux phrases "Non !" et "Pitié !". Il enverra les octets suivants:

4E 6F 6E 20 21 0A 50 69 74 69 C3 A9 20 21 0A 53 54 4F 50 0A
qui se décomposent comme suit :
4E 6F 6E 20 21           \\ les octets de "Non !" encodée en UTF-8
0A                       \\ un octet valant 10
50 69 74 69 C3 A9 20 21  \\ les octets de "Pitié !" encodée en UTF-8
0A                       \\ un octet valant 10
53 54 4F 50              \\ les octets de "STOP" encodée en UTF-8
0A                       \\ un octet valant 10

Dans le squelette ClientUGEPT.java, implémentez la méthode List<String> performRequest(String prompt) qui va :

La méthode ne ferme pas la socketChannel. Si le serveur ne respecte pas le protocole ou envoie plusieurs réponses, la méthode renverra null.

Vous pouvez tester votre client avec le serveur ServerUGEPT.jar. Pour vérifier la réponse, vous pouvez regarder l'affichage du serveur.

$java -jar ServerUGEPT.jar 7777

Votre client prendra en paramètre l'adresse et le port du serveur comme ci-après (en gras, ce que l'utilisateur saisit sur l'entrée standard).

$java fr.uge.net.tcp.exam2024.ex1.ClientUGEPT localhost 7777
What is your prompt ?
Comment réussir un examen de programmation réseau ?
[Pl€as€, just go away., Your pr€s€nc€ is not r€quir€d h€r€., I'm asking you polit€ly to l€av€., I hav€ nothing mor€ to say., This conv€rsation is ov€r., Your company isn't w€lcom€ at th€ mom€nt., Pl€as€ stop talking to m€., L€t's €nd this discussion now.]

Serveur TCP Chrono bloquant fixed prestarted

Toutes les classes demandées dans cet exercice doivent se trouver dans le package fr.uge.net.tcp.exam2024.ex2

Dans cet exercice, vous devez implémenter un serveur TCP multi-thread en mode bloquant, suivant l'architecture fixed prestarted vue en cours, qui implémente le protocole Chrono.

Protocole Chrono

Dans le protocole Chrono, les clients envoient un LONG en BigEndian qui correspond à la valeur renvoyée par System.currentTimeMillis(). Quand le serveur reçoit cette valeur, il appelle lui aussi System.currentTimeMillis() et la différence entre ces deux valeurs est le temps que les données ont mis pour aller du client au serveur. On appelle ce temps : le temps de trajet de la requête. La réponse du serveur sera composée de 3 LONG en BigEndian qui vont correspondre respectivement:

  • au temps de trajet de la question à laquelle on répond,
  • à la moyenne des temps de trajet des questions posées par ce client,
  • à la moyenne des temps de trajet des questions posées pour tous les clients qui sont connectés en ce moment au serveur.

Supposons qu'aucun client n'est connecté au serveur et qu'un client A se connecte au serveur et envoie la requête avec le timestamp 1000. Si le serveur obtient un timestamp (par System.currentTimeMillis()) de 1400 au moment où il reçoit la requête, il calculera un temps de trajet de 400 ms=1400-1000. Il renverra les 3 LONG [400,400,400].

Si la seconde requête du client A a un temps de trajet de 300ms, le serveur renverra [300,350,350] car la moyenne des temps de trajet pour ce client et (400+300)/2 et que ce client est le seul connecté.

Si un second client B se connecte et envoie une requête avec un temps de trajet de 800ms, le serveur lui répondra avec [800,800,500]. En effet, la moyenne des temps de trajet sur tous les clients connectés est de (400+300+800)/3.

Si le client A se déconnecte et que le client B envoie une requête avec un temps de trajet de 700ms, le serveur lui répondra avec [700,750,750].

À partir du squelette de la classe ServerFixedPrestartedChrono.java, écrivez un serveur en mode bloquant suivant l'architecture fixed prestarted vue en cours, pour ce protocole. Le serveur prend comme paramètre le nombre maximum de clients qui peuvent se connecter simultanément.

Pour tester votre serveur, vous pouvez utiliser le client ClientChronoTCP.jar. Ce client envoie un trame à chaque fois que vous appuyez sur la touche entrée. Il affiche les valeurs reçues par le serveur.
Par exemple, vous pouvez lancer votre serveur, qui accepte 3 clients en simultané, sur le port 7777 :

$java fr.uge.net.tcp.exam2024.ex2.ServerFixedPrestartedChrono 7777 3

Vous pouvez le tester depuis au plus 3 terminaux simultanément en lançant un client avec:

$java -jar ClientChronoTCP.jar localhost 7777
Press ENTER to send a request or type QUIT to stop the client.

Sending a request with the timestamp : 1713694647241
Travel time of the request : 373
Average travel time of the requests for this client : 373
Average travel time of the requests for all currently connected clients : 373
Press ENTER to send a request or type QUIT to stop the client.

Sending a request with the timestamp : 1713694653879
Travel time of the request : 399
Average travel time of the requests for this client : 386
Average travel time of the requests for all currently connected clients : 386
Press ENTER to send a request or type QUIT to stop the client.
QUIT
Closing client

Serveur TCP Chrono non-bloquant

Toutes les classes demandées dans cet exercice doivent se trouver dans le package fr.uge.net.tcp.exam2024.ex3

Dans cet exercice, vous devez écrire un serveur TCP en mode non-bloquant, qui implémente le protocole Chrono décrit à l'exercice précédent.

À partir du squelette de la classe ServerNonBlockingChrono.java, écrivez un serveur en mode non-bloquant pour ce protocole. On demande que votre serveur puisse (quand c'est possible) être en OP_READ|OP_WRITE. Attention, le squelette fourni est un serveur pour le protocole Echo, qui suit l'architecture vue en cours. Il est nécessaire de l'adapter et de le faire évoluer : c'est simplement un point de départ.
Tous vos buffers doivent faire 1024 octets.

Pour tester votre serveur, vous pouvez utiliser le client ClientChronoTCP.jar.

Par exemple, vous pouvez lancer votre serveur sur le port 7777 :

$java fr.uge.net.tcp.exam2024.ex3.ServerNonBlockingChrono 7777 
$java -jar ClientChronoTCP.jar localhost 7777
Press ENTER to send a request or type QUIT to stop the client.

Sending a request with the timestamp : 1713694647241
Travel time of the request : 373
Average travel time of the requests for this client : 373
Average travel time of the requests for all currently connected clients : 373
Press ENTER to send a request or type QUIT to stop the client.

Sending a request with the timestamp : 1713694653879
Travel time of the request : 399
Average travel time of the requests for this client : 386
Average travel time of the requests for all currently connected clients : 386
Press ENTER to send a request or type QUIT to stop the client.
QUIT
Closing client