MIM1
TD 9 de POOGL
Threads et Sockets
Vincent BOUDET
Bureau 343 (84-70)
email vboudet@ens-lyon.fr
19 avril 2001
A But du TD
Le but de ce TD est d'utiliser les threads et les sockets pour faire un petit jeu basé sur une architecture client/serveur. Le serveur peut accepter plusieurs connexions client (donc plusieurs joueurs), chaque connexion étant gérée par un thread.
B Les règles
Le serveur choisit un nombre au hasard entre 1 et 10. Un certain nombre de joueurs doivent se connecter avant que la partie commence. Ensuite, suivant leur ordre de connexion, ils jouent chacun leur tour en tapant un numéro au clavier. S'ils ont trouvé, le client s'arrête.
C Description
Voici les classes dont nous aurons besoin :
-
Serveur :
- c'est la classe qui contient la méthode main. C'est elle qui met en place un ServerSocket, qui attend les connexions, et qui créée un
ServerThread chaque fois qu'une connexion est demandée. Elle gère également le tour de jeu, c.a.d. quand tel ou tel joueur joue.
- ServeurThread :
- cette classe s'occupe de gérer la communication entre le serveur et un seul client. Lorsque le client renvoie la valeur à trouver, ce thread s'arrête.
- Synchronizer :
- cette classe définit les méthodes qui permettent à chaque ServerThread d'attendre que tous les joueurs soient connectés ou d'attendre leur tour.
- Client :
- cette classe définit le comportement du client. Celui-ci se connecte au serveur, et attend que le ServerThread dédié à la connexion lui envoie quelque chose. À ce moment, le joueur peut taper un numéro qui est immédiatement envoyé au ServerThread.
C.1 Server.java
Voici le descriptif de cette classe :
C.2 ServerThread.java
Voici le descriptif de cette classe :
-
Cette classe extends Thread.
- Le constructeur a 4 paramètres : la socket de connexion avec le client, le numéro de connexion, l'objet Synchronizer, le numéro à deviner :
public ServerThread(Socket socket, int Id, Synchronizer sync, int rand)
- À partir de la socket, définir BufferedRead in qui sert à recevoir les informations envoyées par le client.
- À partir de la socket, définir PrintWriter out qui sert à envoyer les informations au client.
- Attendre grâce à l'objet Synchronizer que tous les joueurs soient connectés.
- Envoyer aux clients grâce à out le signal de départ (n'importe quelle phrase).
- Faire une boucle while qui se termine quand le Thread reçoit dans tt in le bon numéro.
- Dans cette boucle : attendre grâce à l'objet Synchronizer que ce soit le tour du joueur, lui envoyer une phrase (du genre "à toi de jouer"), recevoir la réponse.
- En sortie de boucle, fermer out, in et la socket.
C.3 Synchronizer.java
Voici le descriptif de cette classe :
-
Le constructeur a un seul paramètre : le nombre de joueurs.
- La méthode oneMore() permet à Server d'incrémenter un compteur. Si ce compteur devient égal au nombre de joueur, elle appelle notifyAll() pour réveiller les ServerThread en attente.
- La méthode waitBegin() permet aux ServerThread d'attendre que tous les joueurs soient connectés.
- La méthode setTurn(int id) permet à Server de fixer le numéro du joueur qui doit jouer. Cette méthode doit bien entendu bloquer si un joueur est en train de jouer ! Et également réveiller les ServerThread dès qu'elle a mis à jour le numéro de tour.
- La méthode waitmyTurn(int myId) permet aux ServerThread d'attendre leur tour de jeu. Tant que le numéro de tour ne correspond pas à myId, le thread doit attendre.
- La méthode endmyTurn(int myId) permet aux ServerThread de dire qu'il vient de terminer son tour. Attention : il faut que celà réveille tous les Threads mais que seul le Server puisse faire quelque chose (en l'occurence changer le tour de jeu).
C.4 Client.java
Voici le descriptif de cette classe :
-
Cette classe n'a qu'une méthode : main.
- Ouvrir une Socket avec en paramètre l'hôte du serveur et le port de connexion. Par exemple :
socket = new Socket("localhost", 4444);
- A partir de la socket, définir BufferedRead in qui sert à recevoir les informations envoyées par le ServerThread.
- À partir de la socket, définir PrintWriter out qui sert à envoyer les informations au ServerThread.
- Définir un Reader à partir de l'entrée standard :
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
- Attendre le commencement du jeu en lisant quelque chose dans in.
- Faire une boucle qui se termine lorsque in.readLine() renvoie null.
- Dans la boucle : afficher le message du ServerThread, lire un chiffre au clavier, l'envoyer au ServerThread.
- En sortie de boucle, fermer out, in et la socket.
D Réalisation
Question D.1
Puisque tout est décrit ci-dessus, à vous de jouer !
This document was translated from LATEX by
HEVEA.