L'examen est composé de trois exercices indépendants qui peuvent être traités dans l'ordre que vous voulez.
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.
Dans cet exercice, vous devez écrire un client TCP en mode bloquant pour le protocole Whois décrit ci-dessous. Ce protocole permet à un client connecté à un serveur Whois de demander un certain nombre d'adresses (IP+port) d'autres clients connectés à ce serveur.
La requête du client est simple entier INT en BigEndian qui correspond au nombre maximum d'adresses qu'il veut recevoir. Le serveur répondra avec une trame au format suivant :
Par exemple, lorsque le client est connecté, il envoie :
00 00 00 03 // INT en BigEndian valant 3 indiquant que le client veut au maximum 3 adresses d'autres clients.
Supposons que le serveur a deux autres clients d'adresses respectives 10.0.0.1 sur le port 3306 et 2001:db8:85a3:8a2e:370:7334:370:7334 sur le port 443. Il peut, par exemple, renvoyer :
00 00 00 02 04 0A 00 00 01 00 00 0C EA 06 20 01 0D B8 85 A3 8A 2E 03 70 73 34 03 70 73 34 00 00 01 BBqui se décompose comme suit :
00 00 00 02 \\ INT en BigEndian valant 2 et indiquant le nombre d'adresses envoyées 04 \\ BYTE valant 4 indiquant une adresse IPv4 0A 00 00 01 \\ octets de l'adresse 10.0.0.1 00 00 0C EA \\ INT en BigEndian valant 3306 donnant le numéro de port 06 \\ BYTE valant 6 indiquant une adresse IPv6 20 01 0D B8 85 A3 8A 2E 03 70 73 34 03 70 73 34 \\ octets de l'adresse 2001:db8:85a3:8a2e:370:7334:370:7334 00 00 01 BB \\ INT en BigEndian valant 443 donnant le numéro de port
Dans le squelette
ClientWhois.java
,
implémentez la méthode List<InetSocketAddress> performRequest(int max)
qui va :
InetAddress.getByAddress(byte[] bytes)
. Si le tableau est de taille 4, l'adresse créée sera une adresse IPv4 et s'il fait 16 octets, ce sera une adresse IPv6.byte[] tab
à partir des octets se trouvant au début de la zone de travail du ByteBuffer buffer
, en utilisant buffer.get(tab)
.
Vous pouvez tester votre client avec le serveur ServerWhoisDummy.jar. Ce serveur n'est pas un vrai serveur, il renvoie simplement une réponse au hasard. Pour vérifier la réponse, vous pouvez regarder l'affichage du serveur.
$java --enable-preview -jar ServerWhoisDummy.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.upem.net.tcp.exam2023.ex1.ClientWhois localhost 7777 How many addresses maximum do you want to get ? 1 [/10.0.0.1:3306] How many addresses maximum do you want to get ? 2 [/[fe80:0:0:0:1:2:3:4]:8080] How many addresses maximum do you want to get ? 4 [/172.16.0.1:443, /192.168.1.1:8080, /[2001:db8:85a3:0:0:8a2e:370:7334]:3306, /[fe80:0:0:0:1:2:3:4]:8080] How many addresses maximum do you want to get ? ...
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 ChatInt présenté ci-dessous et vu en TP.
Les trames circulant entre les clients et le serveur sont des INT en BigEndian.
Quand un message est reçu par le serveur, il le transmet à tous les clients.
À partir du squelette de la classe
ServerFixedPrestartedChatInt.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.
socketChannel.write
est bloquant. Si ce commentaire vous intrigue, ignorez-le.Pour tester votre serveur, vous pouvez utiliser le client ClientChatInt.jar
. Ce client lit au clavier des entiers et les envoie au serveur. Il affiche les entiers reçus du serveur.
Par exemple, vous pouvez lancer votre serveur, qui accepte 3 clients en simultané, sur le port 7777 :
$java fr.upem.net.tcp.exam2223.ex2.ServerFixedPrestartedChatInt 7777 3
Vous pouvez le tester depuis ou au plus 3 terminaux simultanément en lançant un client avec:
$java -jar ClientChatInt.jar localhost 7777
Dans cet exercice, vous devez écrire un serveur TCP en mode non-bloquant, qui implémente le protocole Hash décrit ci-dessous. Dans ce protocole, le client envoie au serveur une chaîne de caractères et le serveur renvoie en entier correspondant au hashcode Java de cette chaîne.
Le client envoie les octets d'une chaîne de caractères terminée par \n encodé en ASCII. Le serveur renvoie un INT en BigEndian dont la valeur est le résultat de la fonction de hashcode de Java sur cette chaîne (sans le \n). Le client peut continuer à faire des requêtes tant qu'il ne ferme pas la connexion.
Par exemple si le client veut envoyer la chaîne de caractères toto, il enverra :
74 6F 74 6F 0Aqui se décompose comme suit :
74 6F 74 6F \\ les octets de la chaîne toto 0A \\ l'octet correspondant \net le serveur répond avec :
00 36 6A 36 \\ 3566134
À partir du squelette de la classe
ServerNonBlockingHash.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 ClientHash.jar
. Ce client lit au clavier une chaîne de caractères, l'envoie au serveur et affiche la réponse du serveur.
Par exemple, vous pouvez lancer votre serveur sur le port 7777 :
$java fr.upem.net.tcp.exam2223.ex3.ServerNonBlockingHash 7777
$java -jar ClientHash.jar localhost 7777 Connecting to server toto Sent: -->toto<-- Received: 3566134 tata Sent: -->tata<-- Received: 3552666