:: Enseignements :: ESIPE :: E4INFO :: 2011-2012 :: Applications réseaux ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) |
TCP, client, serveur, multi-threads
|
Exercice 1 - Client TCP simple
Écrire un client TCP simple (
SimpleTCPClient) qui,
après s'être connecté à un serveur TCP, réalise de manière itérative
les opérations suivantes:
-
lit une ligne de texte (chaîne de caractères terminée par une fin de ligne)
depuis l'entrée standard;
-
écrit cette ligne de texte sur la connexion TCP à destination du serveur
en la terminant par une fin de ligne;
-
lit une ligne de texte (chaîne de caractères terminée par une fin de ligne)
depuis la connexion TCP (réponse en provenance du serveur);
-
affiche cette ligne de texte sur la sortie standard en la terminant par une fin de ligne.
Ce serveur doit être démarré en spécifiant le nom (ou l'adresse IP) du serveur et le port auquel
il doit se connecter ainsi que l'encodage qu'il doit utiliser
pour échanger les chaînes de caractères avec serveur. Par exemple:
% java fr.umlv.tcp.SimpleTCPClient localhost 7777 utf-8
ou encore
% java fr.umlv.tcp.SimpleTCPClient gaspard.univ-mlv.fr 7 ASCII
Pour tester,
gaspard.univ-mlv.fr implémente sur son port 7 un service Echo,
mais vous pouvez également installer sur votre propre machine le petit serveur
TCPUpperCaseServer.jar, qui prend
en argument le nombre de client qu'il est capable de servir simultanément, le port
sur lequel il attend les connexions de clients et l'encodage des chaînes de caractères
qu'il utilise. Par exemple, pour tester votre client, lancez-le sur votre machine par
% java -jar TCPUpperCaseServer.jar 5 7777 utf-8
Ce serveur,
TCPUpperCaseServer.jar, accepte un 4ème argument optionnel
sur la ligne de commande, qui représente sa "fiabilité" (non pas du réseau, comme
en UDP, car TCP est fiable, mais bien du serveur). En effet, avec une fiabilité de
0.5, le serveur ne répondra aléatoirement qu'à 50% des lignes reçues...
En relancant ce serveur comme ceci:
% java -jar TCPUpperCaseServer.jar 5 7777 utf-8 0.5
quels sont les problèmes que pose votre client
SimpleTCPClient?
Rencontrez vous les mêmes problèmes avec netcat (
nc localhost 7777)?
Développez un nouveau client, TCPClient, qui permet de palier ces inconvénients:
il doit permettre à tout moment d'envoyer une ligne au serveur, et simultanément
à tout moment d'afficher une ligne en provenance du serveur, et ce de manière décorrélée.
Lorsque le serveur ferme la socket (s'il meurt par exemple), comment pouvez
vous arrêter d'écouter sur l'entrée standard (clavier) du client?
Exercice 2 - Serveur de mise en majuscules
On souhaite maintenant écrire notre propre classe TCPUpperCaseServer qui
implante un serveur TCP qui renvoit les lignes aux clients après les avoir
mises en majuscule.
Ce serveur crée une socket serveur (objet de la classe
java.net.ServerSocket), sur un port spécifié sur la ligne de commande,
puis est "démarré". Il attend alors une connexion d'un client, via la méthode
accept() appelée sur l'objet ServerSocket.
Lorsqu'un client contacte le serveur, la méthode accept()
du serveur retourne un objet de la classe Socket.
Celle-ci est alors dite socket de service. Le serveur peut ainsi satisfaire
la ou les requêtes successives émises par le client sur la socket de service.
Cette connexion peut être fermée par le client, ou par le serveur s'il reçoit
une ligne ne contenant qu'un seul point ('.').
Dans un premier temps, vous écrirez une méthode launchIterative()
qui implante un serveur itératif: lorsque les différentes requêtes du premier client
sont traitées, la socket de service peut être fermée, et une nouvelle
connexion peut être élue comme socket de service par un nouvel appel à accept()
sur l'objet ServerSocket.
Le principe du serveur
TCPUpperCaseServer, pour le traitement des
requêtes d'une socket de service qu'il vient d'accepter, est le suivant :
-
Les données doivent être envoyées par le client ligne par ligne, et une
ligne ne contenant qu'un seul point ('.') termine la session.
Pour chaque ligne reçue par le client, le serveur la met en majuscules et la
renvoie au client (le serveur doit utiliser l'encodage de caractères
spécifié sur la ligne de commande, comme le jar executable de l'exercice précédent).
-
Si la connexion reste trop longtemps ouverte sans activité, elle est fermée par le
serveur.
Que se passe-t-il si deux clients tentent d'accéder au service simultanément?
Est-ce que le comportement est le même qu'en UDP?
Dans un second temps, remplacez l'appel à la méthode launchIterative()
par un appel à une méthode launchConcurrent() qui permet à plusieurs
clients d'être servis simultanément. Discuter des différentes options possibles
d'implémentation d'un tel serveur concurrent.
Vous pouvez implanter les mêmes services que ceux fournis par le
serveur TCPUpperCaseServer.jar plus haut, c'est-à-dire qui
fixe le nombre de clients maximum pouvant être servis simulténément.
© Université de Marne-la-Vallée