:: Enseignements :: ESIPE :: E4INFO :: 2011-2012 :: Applications réseaux ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) |
Représentation des données en TCP, multi-threads, multi-flux coordonnés
|
Exercice 1 - TCP Longue Somme de Long
On souhaite mettre en place un service de calculette permettant à un client
de demander le résultat de la somme de plusieurs entiers longs
(long sur 64 bits).
Le client doit envoyer chaque opérande un par un en binaire dans
la convention "network order" (i.e. big endian -- l'octet de poids
fort est enregistré à l'adresse mémoire la plus petite). À chaque envoi
d'opérande, la somme cumulée de l'ensemble des opérandes envoyés par ce client
est renvoyé par le serveur vers le client. Lorsque le client envoit un
opérande nul (i.e. 0), le serveur renvoit la somme cumulée au client et
réinitialise à 0 le compteur qu'il maintient.
Bien sûr, il est possible de réutiliser les méthodes écrites pour
le même exercice en UDP, mais nous allons faire autrement (en
l'occurrence, plus simplement)...
-
En UDP, lorsque le serveur reçoit un datagramme,
on peut supposer qu'on dispose des 8 octets du long attendu
(pour peu que le client soit codé correctement). Est-ce le cas en TCP?
-
Lorsque qu'on lit une ligne de texte sur une connexion TCP
(comme dans les clients ou les serveurs de mise en majuscule codés
précédemment), on utilise un BufferedReader ou une classe
équivalente qui "bufferise" tous les octets lus sur la connexion jusqu'à
trouver les octets marquant la fin d'une ligne. Mais alors comment faire
pour lire un long? et en big endian?
-
Écrire un serveur TCPLongSumServer qui réalise le service
de somme décrit ci-dessus pour les clients TCP qui se connectent à lui.
Au moins 10 clients doivent pouvoir être traités simultanéments.
Pour tester, vous devrez également écrire un client qui lit les long
sur l'entrée standard et les envoit en "network order" au serveur.
-
Modifier votre serveur pour que, en plus
de stocker la somme "propre" à un client, le serveur cumule dans un compteur global
la somme de toutes les opérandes envoyées par tous les clients depuis le démarrage du serveur.
Vous pouvez faire afficher cette valeur dans la console du serveur
Quelle précaution devez vous prendre lors de l'incrémentation de ce compteur global?
-
Imaginez maintenant qu'il y a une valeur "maudite" du compteur global
(par exemple 666666666666666666): faites en sorte que le client qui a envoyé le dernier
opérande qui, lorsqu'il a été ajouté au compteur global, lui a permis d'atteindre exactement
cette valeur, soit "tué", c'est à dire qu'on lui ferme la connexion.
Exercice 2 - Proxy TCP
On souhaite écrire une application
Proxy qui permet de relayer
entre un client et un serveur toutes les données transitant sur une connexion TCP.
Le proxy est lancé sur une machine en fournissant un numéro de port local
sur lequel il attend les connexions des clients, ainsi
que le nom et le numéro de port du serveur distant qui rend le service recherché
par le client. Par exemple, dans le cas suivant:
java fr.umlv.tcp.Proxy 9999 remoteHostServer 5555
on imagine qu'un serveur est hébergé par la machine "remoteHostServer"
et qu'il attend des connexions sur son port 5555.
Lorsque notre proxy reçoit, sur son port 9999,
une demande de connexion depuis un client, il accepte cette connexion et
doit à son tour demander l'établissement d'une connexion sur le port
5555 de "remoteHostServer".
Une fois ces deux connexions établies, toute information en provenance
du client doit être relayée à destination du "remote" serveur et toute
information en provenance du remote serveur doit être relayée à destination
du client; pour le client, le proxy est "transparent".
On doit veillez à ce que la fermeture des deux connections soit la plus cohérente
possible en fin de communication.
Dans un premier temps, on ne se souciera pas du nombre de thread crées et
on pourra en créer deux par client servis; en revanche, plusieurs clients
doivent pouvoir être servis simultanément.
© Université de Marne-la-Vallée