:: Enseignements :: Master :: M1 :: 2015-2016 :: Programmation d'applications réseaux ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) |
Clients TCP simples
|
Le principe de TCP est de disposer d'une connexion qui offre une communication bi-directionnelle
sous la forme de deux flux. Tant que ces flux ne sont pas "fermés", rien ne permet de savoir, a priori,
si on a reçu l'intégralité de ce qui a été émis par l'interlocuteur ou s'il reste des données à reçevoir: c'est la "segmentation".
Il faut donc, quelque soit le principe ou le protocole retenu, se donner les moyens de savoir si il
reste des choses à lire ou pas.
Une technique basique consiste à attendre que le flux de lecture soit fermé pour
considérer qu'il n'y a plus rien à lire!
Une autre consiste à utiliser un protocole qui décrit précisément la nature
et la taille des données attendues.
Il est aussi possible de détecter dans les informations qu'on reçoit des données "utiles"
identifiant la fin de la réponse (comme une fin de ligne par exemple)...
Exercice 1 - Fermez la porte en sortant
On cherche a réaliser un client TCP très simple. Le protocole est le suivant.
Le client établit la connexion avec le serveur, puis écrit une chaîne en UTF-8
à destination du serveur et ferme la connection en écriture. Ensuite il lit
sur la connexion une chaîne de caractères en UTF-8 dont la fin est signalée par
la fermeture de la connexion en lecture.
- En partant du fichier ClientEOS.java,
écrivez la fonction getFixedSizeResponse qui prend en paramètre la chaîne de
caractères à envoyer, l'adresse du serveur et la taille du buffer de réception.
Si la réponse du serveur dépasse la taille du buffer, on ignore la fin de la réponse.
-
Ecrivez ensuite la fonction getUnboundedResponse qui doit lire la réponse
quelque soit la taille de la chaîne de caractères renvoyée par le serveur.
Exercice 2 - Le protocole, y'a que ça de vrai
Le client précédent a deux inconvénients majeurs: il n'est pas très efficace car
demande de manipuler plusieurs fois les données reçues pour reconstituer la réponse,
et surtout il ne permet pas de réutiliser la connexion pour une deuxième requête.
On va donc maintenant écrire un client qui envoit et reçoit des informations dont le
format est précisé par un protocole.
Le but de l'exercice est de réaliser un client qui interroge un serveur devant
réaliser la somme d'une liste d'entiers
long en suivant le protocole TCP suivant:
- le client se connecte au serveur
- le client envoie un INT (en big endian) donnant le nombre d'opérandes de l'opération à réaliser,
puis chacun des opérandes qui sont des LONG en big endian;
- le client lit ensuite la réponse du serveur qui est un LONG correspondant à la somme des opérandes.
- le serveur ne ferme pas la connection qui peut donc être utilisée pour faire une autre somme
en repartant à l'étape 2.
En partant du fichier
ClientLongSum.java,
vous devez réaliser un client qui prend en paramètre l'adresse et le port du serveur.
Il se lancera par exemple avec:
java fr.upem.net.tcp.ClientLongSum localhost 7777
La méthode
requestSumForList(SocketChannel sc, List<Long> list) de votre client
doit envoyer la liste d'opérandes au serveur en respectant le protocole, puis lire la réponse du
serveur et la renvoyer.
Si le serveur ferme la connection avant d'avoir fini l'échange, votre client
affichera le message:
Connection with server lost.
et quittera.
Vous pouvez tester votre client en lancant le serveur
ServerLongSum.jar comme suit:
java -jar ServerLongSum.jar 7777
Pour tester le cas où le serveur ferme la connection de manière
imprévue, vous lancerez le serveur avec l'option
-bug qui
introduit une probabilité que le serveur ferme la connection.
java -jar ServerLongSum -bug 7777
Exercice 3 - Bout à bout
Le même genre de protocole peut être mis en place pour échanger des chaînes de caractères.
Le but de cet exercice est de réaliser un client qui se connnecte à un serveur de
concatenation de chaînes avec le protocole TCP suivant:
-
le client envoie un INT (en big endian) donnant le nombre de chaînes de caractères,
puis envoie chacune de ces chaînes encodée par un INT (pour la taille en nombre d'octets
de la chaîne encodée en UTF-8) suivi des octets représentant la chaîne en UTF-8.
-
le serveur répond avec une seule chaîne, représentée sous le même format, correspondant
à la concatenation de toutes les chaînes, séparées par des virgules.
Vous réaliserez un client
ClientConcatenation.java qui prend en paramètre
l'adresse et le port du serveur. Il se lancera par exemple avec:
java upem.net.tcp.ClientConcatenation localhost 7777
Votre client va lire des chaînes au clavier jusqu'à ce qu'il lise une chaîne vide.
Il enverra ensuite ces chaînes (sans la chaîne vide) au serveur en respectant le protocole
et affichera la réponse du serveur.
Si le serveur ferme la connection avant d'avoir envoyé la réponse, votre client
affichera le message:
Connection with server lost.
et quittera.
Vous pouvez tester votre client en lancant le serveur
ServerConcatenation.jar comme suit:
java -jar ServerConcatenation 7777
Le serveur écoute sur le port 7777.
© Université de Marne-la-Vallée