Afin qu’un responsable pédagogique de la plateforme puisse consulter la liste des étudiants d’une
équipe, une architecture client/serveur est mise en place. Son schéma est donné par la figure suivante :
1- Quel est le rôle d’un serveur d’application ?
Un serveur d’application s’occupe de toutes les opérations de base d’une application et offre aux clients légers des services distants.
2- Donner la classe d’adressage correspondante à l’adresse IP du serveur d’application : 192.168.1.20
IP du serveur d’application : 192.168.1.20 est une adresse de classe C car l’octet du poids fort qui est 192 est compris entre 192 et 223.
3- La communication entre le client et le serveur d’application peut se faire en utilisant les sockets TCP.
MÉTHODE 1 : Socket TCP
Classe : Client TCP
public class Client {
private Socket sc=null;
private PrintWriter out=null;
private ObjectInputStream in=null;
public Client(String IP,int port){
try {
sc=new Socket(IP,port);
out=new PrintWriter(sc.getOutputStream(),true);
in=new ObjectInputStream(sc.getInputStream());
} catch (IOException e) {
System.out.println("error");
}
}
public ArrayList<Etudiant> getListeEtudiants(int numEq){
try {
out.println(numEq);
return (ArrayList<Etudiant>)in.readObject();
} catch (IOException | ClassNotFoundException e) {
return null;
}
}
}
Ce code est une classe nommée « Client » qui permet de se connecter à un serveur distant et de recevoir une liste d’étudiants à partir du serveur. Voici une explication détaillée de chaque partie du code:
- Déclaration des variables de classe:
La classe « Client » a trois variables de classe:
- sc (Socket): c’est un objet de type Socket qui représente la connexion réseau entre le client et le serveur.
- out (PrintWriter): c’est un objet de type PrintWriter qui est utilisé pour envoyer des données au serveur.
- in (ObjectInputStream): c’est un objet de type ObjectInputStream qui est utilisé pour recevoir des données du serveur.
- Constructeur:
Le constructeur de la classe prend deux paramètres: IP et port. Il tente ensuite de se connecter au serveur en créant un objet Socket avec l’adresse IP et le port donnés en paramètres. Ensuite, il crée les objets PrintWriter et ObjectInputStream pour envoyer et recevoir des données du serveur.
- La méthode getListeEtudiants:
Cette méthode prend un paramètre « numEq » qui représente le numéro de l’équipe pour laquelle nous voulons obtenir la liste d’étudiants. Elle envoie le numéro de l’équipe au serveur en utilisant l’objet PrintWriter « out ». Ensuite, elle attend la réponse du serveur en utilisant l’objet ObjectInputStream « in » et retourne la liste d’étudiants récupérée.
Si une exception est levée lors de l’envoi ou de la réception de données, la méthode retourne null.
En résumé, ce code représente une classe client qui se connecte à un serveur distant pour recevoir une liste d’étudiants pour une équipe spécifique.
Classe : Serveur TCP
public class Serveur {
private ServerSocket ss;
private Socket sc=null;
private BufferedReader in = null;
private ObjectOutputStream out= null;
public void startServer(){
int numEq;
try{
ss=new ServerSocket(3000);
while(true) {
sc=ss.accept();
in=new BufferedReader(new InputStreamReader(sc.getInputStream()));
out=new ObjectOutputStream(sc.getOutputStream());
while(true) {
numEq=Integer.parseInt(in.readLine());
if(numEq<0) break;
out.writeObject(getEtudiants(numEq));
out.flush();
}
}
}catch(Exception ex) {
System.out.println("Error"); }
}
public ArrayList<Etudiant> getEtudiants(int numEq)
{ // Le code source de la méthode getEtudiants est non demandé }
}
Ce code représente une classe nommée « Serveur » qui permet d’écouter les connexions de clients et de leur fournir une liste d’étudiants pour une équipe spécifique. Voici une explication détaillée de chaque partie du code:
- Déclaration des variables de classe:
La classe « Serveur » a quatre variables de classe:
- ss (ServerSocket): c’est un objet de type ServerSocket qui représente le serveur qui écoute les connexions des clients.
- sc (Socket): c’est un objet de type Socket qui représente la connexion réseau entre le serveur et le client.
- in (BufferedReader): c’est un objet de type BufferedReader qui est utilisé pour lire les données envoyées par le client.
- out (ObjectOutputStream): c’est un objet de type ObjectOutputStream qui est utilisé pour envoyer des données au client.
- La méthode startServer:
Cette méthode crée un objet ServerSocket qui écoute les connexions des clients sur le port 3000. Elle attend ensuite qu’un client se connecte en utilisant la méthode accept de ServerSocket. Lorsqu’un client se connecte, elle crée un objet BufferedReader et ObjectOutputStream pour recevoir et envoyer des données à ce client.
La méthode utilise ensuite une boucle while pour lire le numéro d’équipe envoyé par le client à travers l’objet BufferedReader. Si le numéro d’équipe est négatif, cela signifie que le client veut fermer la connexion et la boucle se termine. Sinon, la méthode appelle la méthode getEtudiants avec le numéro d’équipe et envoie la liste d’étudiants au client à travers l’objet ObjectOutputStream.
- La méthode getEtudiants:
Cette méthode prend un paramètre « numEq » qui représente le numéro de l’équipe pour laquelle nous voulons obtenir la liste d’étudiants. Elle renvoie une liste d’étudiants correspondant au numéro d’équipe donné.
Si une exception est levée lors de l’envoi ou de la réception de données, la méthode startServer affiche « Error » sur la console.
En résumé, ce code représente une classe serveur qui écoute les connexions des clients et fournit une liste d’étudiants pour une équipe spécifique. Le serveur utilise des objets BufferedReader et ObjectOutputStream pour lire et envoyer des données aux clients et la méthode getEtudiants pour récupérer la liste d’étudiants correspondante.
MÉTHODE 2 : Objets partagés RMI
Classe : Serveur RMI
public Interface Service extends Remote {
public ArrayList<Etudiant> getListeEtudiants(int numEq) throws RemoteException;
}
//...................
public class Serveur extends UnicastRemoteObject implements Service {
public Serveur() throws RemoteException {}
// ---------------------------------
@Override
public ArrayList<Etudiant> getListeEtudiants(int numEq) throws RemoteException
{ return getEtudiants(numEq);}
//------------------------------------------------------------
public ArrayList<Etudiant> getEtudiants(int numEq)
{ }
public static void main(String [] args) throws Exception {
LocateRegistry.createRegistry(1099);
Serveur obj=new Serveur();
Naming.rebind("rmi://192.168.1.20:1099/OBJ", obj);
}
}
Le code ci-dessus représente une interface RMI (Remote Method Invocation) nommée « Service » et une classe Serveur qui implémente cette interface.
L’interface « Service » étend l’interface « Remote », ce qui signifie qu’elle est destinée à être utilisée pour appeler des méthodes à distance. Elle a une seule méthode nommée « getListeEtudiants » qui prend un paramètre « numEq » et renvoie une liste d’étudiants correspondant au numéro d’équipe donné. La méthode peut potentiellement lever une exception de type RemoteException, qui est une exception standard dans les communications RMI.
La classe « Serveur » implémente l’interface « Service » et étend la classe « UnicastRemoteObject » qui fournit une implémentation standard pour les objets RMI. Le constructeur de la classe est défini pour lancer une exception de type RemoteException.
La méthode getListeEtudiants de la classe Serveur utilise la méthode getEtudiants pour récupérer la liste d’étudiants correspondante et la renvoie. Cette méthode override la méthode getListeEtudiants de l’interface « Service ».
La méthode main est utilisée pour lancer le serveur RMI. Elle utilise la méthode « createRegistry » de la classe « LocateRegistry » pour créer un objet de registre RMI et utilise la méthode « Naming.rebind » pour enregistrer l’objet Serveur dans le registre RMI avec un nom d’objet « OBJ ».
En résumé, le code ci-dessus représente une implémentation RMI pour fournir une méthode getListeEtudiants qui peut être appelée à distance et fournit une liste d’étudiants pour un numéro d’équipe spécifique. La méthode main est utilisée pour lancer le serveur RMI et enregistrer l’objet Serveur dans le registre RMI pour que les clients puissent y accéder.
Classe : Client RMI
public class Client{
private Service ob;
// ---------------------------------
public Client() throws Exception
{
ob=(Service)Naming.lookup("rmi://192.168.1.20:1099/OBJ");
}
// ---------------------------------
public ArrayList<Etudiant> get(int numEq) throws RemoteException
{
return ob.getListeEtudiants(numEq);
}
}
Le code ci-dessus représente une classe « Client » pour accéder à distance à une méthode RMI « getListeEtudiants » implémentée dans un serveur distant.
La classe « Client » a un objet « ob » de type « Service » qui représente l’interface de la méthode distante. Le constructeur de la classe lance une exception de type Exception, qui peut être levée si la recherche de l’objet dans le registre RMI échoue. La méthode « Naming.lookup » est utilisée pour trouver l’objet dans le registre RMI avec l’URL « rmi://192.168.1.20:1099/OBJ ».
La méthode « get » prend un paramètre « numEq » qui est utilisé pour récupérer une liste d’étudiants correspondante en appelant la méthode « getListeEtudiants » sur l’objet « ob ». Cette méthode peut lever une exception de type RemoteException si la communication avec le serveur échoue.
En résumé, le code ci-dessus représente une implémentation RMI client pour accéder à une méthode getListeEtudiants implémentée sur un serveur distant. La classe « Client » utilise l’objet « ob » pour appeler la méthode distante en utilisant le paramètre « numEq » et récupère la liste d’étudiants correspondante.