Master 1 Informatique Programmation Répartie et Architecture N Tiers
 

TD-TP - n° 1 : Programmation Distribuée en C avec RPC

Durée: 3H

 
Denis Caromel , Brian Amedro
Université Nice-Sophia Antipolis , Département Informatique

1.  Installation et test de l'application rdict

1.1.  Installation de l'archive rdict

Récupérez l'archive td01.zip qui se trouve sur la page web du cours

http://www-sop.inria.fr/oasis/Denis.Caromel/ProgRpt/
					
et installez-la dans le répertoire de votre choix selon la procédure habituelle unzip td01.zip

L'application client-serveur rdict a été initialement conçue par Comer et Stevens pour servir d'exemple dans leur livre Internetworking with TCP/IP Vol 3: Client-Server programming and Applications , Prentice-Hall puis a été par la suite successivement modifiée par Michel Syska, Julien Vayssière (qui a également produit la première version de ce TD) et Denis Caromel.

1.2. Création des programmes client et serveur

L'archive contient tous les fichiers source en C, le fichier RPCL rdict.x ainsi qu'un fichier Makefile .

  1. Commencez par regarder le Makefile afin de comprendre l'appel à rpcgen , et la création des exécutables du serveur et du client.
  2. Il ne reste plus qu'à lancer make , ce qui a pour effet de

1.3. Test

Pour les besoins du TD, nous ferons tourner le serveur sur la machine locale. Le client pourra être lancé depuis n'importe quelle machine, y compris la machine locale.

Pour lancer le serveur :
  > rdictd
et pour lancer le client :
  > rdict <nom de la machine sur laquelle tourne le serveur>
  1. Vérifiez qu'un programme RPC a bien été enregistré à votre nom sur la machine.
  2. Dans le cas de plusieurs serveurs rdictd lequel est choisi ?
  3. Vous pouvez ensuite entrer les commandes suivantes dans rdict :
  4. Utilisez à plusieurs le même serveur, et voyez l'effet de vos requêtes concurrentes.

2. Programmation

2.1. Comprendre ce qu'il se passe

Pour la suite du TD, il est important de bien comprendre la manière dont les différentes parties de l'application collaborent entre-elles. En particulier, il est important de faire la différence entre les fichiers générés par rpcgen et ceux fournis dans l'archive rdict.tar.

  1. Du côté client, on pourra par exemple suivre la suite des appels de fonction entre l'entrée d'une commande par l'utilisateur (le code correspondant se trouve dans rdict.c et l'appel à la procédure distante correspondante, au niveau du stub client.
  2. Du côté serveur, on pourra suivre ce qu'il se passe depuis la réception d'un appel de procédure au niveau du stub serveur jusqu'à l'exécution de la fonction demandée.

2.2. Ajout de fonctions simples

Ajoutez quelques fonctions à rdict, par exemple:

2.3. Passage de types complexes dans l'application rdict

Le but de cet exercice est de montrer comment passer un type complexe en résultat d'une fonction RPC-C. Il est intéressant de voir que cela n'est pas simple alors que d'autres langages comme Java font cela de manière transparente.

Nous voulons écrire une fonction tous() qui retourne tous les mots du dictionnaire. Le résultat de cette fonction sera une liste chaînée de mots. Une liste chaînée n'étant pas un type simple connu de RPCGen. Il faut la décrire dans le fichier rdict.x. Comme la syntaxe n'est pas facile nous la donnons ici

/* Pour lister tous les mots, Exemple de structure de données complexes */
const MAXMOTLONG = 255; /* Taille maxi mot */
typedef string chaine_mot<MAXMOTLONG>; /* Un mot pour chaînage, indispensable */
typedef struct  list_mots* suivant_list; /* Suivant dans la liste */

struct list_mots {
    chaine_mot mot; /* Le mot */
    suivant_list mot_suivant;  /* Pointeur vers le suivant */
};

Ajoutez maintenant dans le fichier rdict.x la fonction TOUS qui retourne un résultat de type suivant_list.

Modifiez ensuite les autres fichiers (rdict.c, rdict_cif.c, rdict_server.c et rdict_srp.c) pour terminer l'implémentation.

/*------------------------------------------------------------------------
 * tous : retourne tous les mots du dictionnaire
 *------------------------------------------------------------------------
 */
suivant_list
tous ()
{
...
}

Tester que ca fonctionne.