Devoir Surveillé Systèmes Répartis et Applications
Ce devoir surveillé porte sur les systèmes répartis et leurs applications. Il évalue des compétences en compréhension des concepts fondamentaux, programmation RPC (Remote Procedure Call) et RMI (Remote Method Invocation), ainsi que la capacité à écrire et analyser du code distribué.
D'après le document Devoir Surveillé Systèmes Répartis et Applications
Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.
Document source
Programming, Distributed Systems, Remote Method Invocation · DOCX · 8 pages · 2011
Ce devoir surveillé porte sur les systèmes répartis et leurs applications. Il évalue des compétences en compréhension des concepts fondamentaux, programmation RPC (Remote Procedure Call) et RMI (Remote Method Invocation), ainsi que la capacité à écrire et analyser du code distribué.
Exercice 1 : Questions diverses
Cette première série de questions demande d'expliquer des notions clés des systèmes répartis, de citer des formes de transparence, et de décrire des fonctions et commandes spécifiques.
Quelle est la différence fondamentale entre les termes de chacune des paires suivantes ?
- Un noyau monolithique et un micronoyau : Un micronoyau est implanté à la fois dans l’espace mémoire privilégié et dans l’espace utilisateur, tandis qu’un noyau monolithique est implanté uniquement dans l’espace mémoire privilégié.
- API et IDL : Une API (interface programmatique) est une interface de programmation, alors que l’IDL (Interface Description Language) est un langage de description d’interface qui masque les problèmes liés à l’hétérogénéité des systèmes.
- RPC et RMI : RMI (Remote Method Invocation) est une forme de RPC basée sur les objets.
- Passage par copie et passage par référence : Le passage par référence est utilisé pour un objet distant, tandis que le passage par copie concerne les objets locaux qui doivent être sérialisables.
Citez au moins deux formes de transparence pour les systèmes répartis.
Exemples : transparence d’accès, transparence de localisation, transparence de migration.
À quoi sert un serveur de noms ? Donnez deux exemples significatifs.
Un serveur de noms (ou annuaire) sert essentiellement à publier et à rechercher/ localiser un service distant. Exemples : Portmapper et rmiregistry.
À quoi sert la version d’un programme RPC ?
Elle favorise l’indépendance des mises à jour entre serveur et client.
À quoi sert la fonction
CLIENT * clnt_create(server, PROG, VERS, path)?Elle permet de connecter le client au serveur hébergeant le programme PROG de version VERS.
Que fait la commande rpcinfo –u localhost 53687093 ?
Elle appelle la procédure 0 du programme numéro 53687093 sur la machine localhost. C’est un genre de ping pour vérifier que le réseau fonctionne et que le serveur est actif.
Exercice 2 : Programmation micro-RPC
On demande ici de spécifier un service RPC avec trois fonctions, d’écrire le code serveur en C, puis d’expliquer comment un client se connecte, appelle ces fonctions et se déconnecte.
1. Spécification du service en RPCL
// spécification Micro_rpc.x
struct param {
string c1, c2;
};
typedef struct param Param;
/*** définition du programme avec les 3 fonctions ***/
program MICRO_RPC {
version MICRO_VERS_1 {
void micro_NULL(void) = 0;
int doubler(int) = 1;
string concat(Param) = 2;
void increm(void) = 3;
} = 1;
} = 0x20000001;
Chaque fonction est associée à un numéro d’opération. Le programme a un identifiant hexadécimal unique.
2. Développement du fichier serveur.c en C
#include <string.h>
#include "micro_rpc.h"
static int nb = 0;
int * doubler_1_svc(int *argp, struct svc_req *rqstp) {
static int result;
result = *argp * 2;
return &result;
}
char * concat_1_svc(Param *argp, struct svc_req *rqstp) {
static char result[256]; // buffer statique pour la chaîne résultante
strcpy(result, argp->c1);
strcat(result, argp->c2);
return result;
}
void * increm_1_svc(void *argp, struct svc_req *rqstp) {
nb++;
return NULL;
}
Remarques :
- La variable
resultdansdoubler_1_svcest statique pour rester valide après le retour. - Dans
concat_1_svc, on utilise un buffer statique pour retourner la chaîne concaténée. - La fonction
increm_1_svcincrémente un compteur localnbet retourne NULL car elle est de type void.
3. Connexion, appel et déconnexion côté client
CLIENT *clnt;
int x = 5; // exemple de valeur
// Connexion au serveur
clnt = clnt_create(host, MICRO_RPC, MICRO_VERS_1, "tcp");
if (clnt == NULL) {
// gestion d'erreur
}
// Appel aux fonctions distantes
increm_1(NULL, clnt);
x = *doubler_1(&x, clnt);
Param p;
p.c1 = "Bonjour ";
p.c2 = "monde";
char *res = concat_1(&p, clnt);
// Déconnexion du serveur
clnt_destroy(clnt);
Le client crée une connexion avec clnt_create, appelle les fonctions distantes en passant les arguments, puis ferme la connexion avec clnt_destroy.
Exercice 3 : Application Banque en RMI
Ce dernier exercice porte sur une application bancaire distribuée utilisant RMI. Il demande d’écrire des interfaces, d’expliquer la sérialisation, d’implémenter une classe serveur, et d’analyser l’exécution côté client et serveur.
1. Interface Banquier
import java.rmi.RemoteException;
import java.rmi.Remote;
public interface Banquier extends Remote {
public Compte creeCompte(Personne p) throws RemoteException;
}
L’interface étend Remote et déclare la méthode distante creeCompte qui prend un objet Personne et retourne un objet Compte.
2. Conditions sur l’objet Personne et fichiers nécessaires côté serveur
L’objet Personne est implémenté côté client et passé par copie lors de l’appel de creeCompte(Personne p).
- Condition :
Personnedoit être sérialisable, c’est-à-dire implémenterjava.io.Serializable. - Fichiers nécessaires côté serveur :
Le serveur a besoin de
Personne.class(et éventuellementPersonneImpl.classsi l’implémentation est séparée), ainsi queCompte.classetCompteImpl.classpour exécuter la méthode.
3. Implémentation de l’interface Compte : CompteImpl
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
public class CompteImpl extends UnicastRemoteObject implements Compte {
Personne proprio;
float solde = 0;
public CompteImpl(Personne p) throws RemoteException {
proprio = p;
}
public void verse(float montant) throws RemoteException {
solde += montant;
}
public float getSolde() throws RemoteException {
return solde;
}
}
Cette classe étend UnicastRemoteObject pour être un objet distant et implémente l’interface Compte. Elle stocke un propriétaire Personne et un solde, et fournit les méthodes pour verser de l’argent et obtenir le solde.
4. Analyse d’exécution des méthodes côté client et serveur
Exécution de co.verse(12) :
Cette méthode s’exécute côté serveur car Compte est un objet distant implémenté sur le serveur (héritant de UnicastRemoteObject). L’appel est donc un appel distant.
Exécution de getNom() dans creeCompte(Personne p) :
L’objet Personne est passé par copie au serveur, donc la méthode getNom() s’exécute sur la copie locale côté serveur.
5. Fichiers .class nécessaires côté client sans chargement dynamique
Personne.class(et éventuellementPersonneImpl.class) : pour créer et sérialiser l’objetPersonneà envoyer au serveur.Compte.class: pour connaître les méthodes offertes par l’interfaceCompte(ex.verse).Banquier.class: pour connaître les services offerts par l’objet distantBanquierdont la référence est récupérée via le registre RMI.
Méthode
Ce devoir récompense la maîtrise des concepts fondamentaux des systèmes répartis, notamment la distinction précise entre notions proches (ex. noyau monolithique vs micronoyau), la compréhension des mécanismes RPC et RMI, ainsi que la capacité à écrire et analyser du code distribué en C et Java.
Il est essentiel de respecter les notations et définitions données dans l’énoncé, notamment les signatures des fonctions RPC et les conventions de sérialisation en RMI. Les réponses doivent être précises, concises, et montrer clairement les étapes de raisonnement, notamment dans la programmation RPC où la gestion des types et des buffers est cruciale.
Les erreurs fréquentes punies sont :
- Confusion entre notions proches (ex. API vs IDL, RPC vs RMI).
- Oublier la sérialisation ou les fichiers nécessaires pour le fonctionnement client-serveur.
- Ne pas justifier l’exécution côté client ou serveur dans RMI.
- Omettre les étapes intermédiaires dans les appels RPC (connexion, appel, déconnexion).
- Ne pas respecter les signatures et types dans la programmation RPC.
Enfin, la rigueur dans la syntaxe et la gestion mémoire (en C) est aussi évaluée.
Commentaires
Aucun commentaire pour le moment. Posez la première question.