Département INFormatique 
  CSC4508/M2 : Concepts des systèmes d'exploitation et mise en œuvre sous Unix


    Contenu



Éléments d'architecture client-serveur

Corrigés

Exercice 1 : M. et Mme...

Dans cet exercice, on se propose d'écrire un serveur de "M. et Mme" :
  • Le client lit, sur sa ligne de commande, le nom de famille de "M. et Mme". Il l'envoie au serveur.
  • Le serveur cherche ce nom de famille dans le fichier mEtMme.txt :
    • s'il le trouve, il renvoie le nom du fils, de la fille ou bien des enfants
    • sinon il renvoie le message "Désolé, je ne le connais pas"
  • Le client affiche le message reçu du serveur.

Préparation

Se placer dans un répertoire de travail
tar xvfz q1.tgz
cd Q1

Question 1.1

Le code qui vous est fourni dans le répertoire Q1 comprend un client et un serveur qui fonctionnent comme dans l'exemple fourni en cours sur les files de messages :
  1. concernant le client :
    1. il crée une file de message dont le nom est suffixé par son "pid" (de manière à ne pas interférer avec d'autres clients potentiels) ;
    2. il se "connecte" au serveur via la file de messages "/client-serveur" (créée par le serveur) ;
    3. la requête du client contient non seulement le "M. et Mme" cherché, mais aussi le nom de la file de messages a été créée en 1.1 par le client et sur laquelle le client attend la réponse du serveur ;
  2. concernant le serveur :
    1. sur réception d'une requête client, le serveur cherche dans le fichier une ligne qui commence par le "M. et Mme" mentionné dans la requête ;
    2. s'il la trouve, il renvoie l'ensemble de la ligne sur la file de messages mentionnée dans la requête ;
    3. sinon, il renvoie "Desole, je ne le connais pas".
Programmer le serveur de sorte qu'il crée un thread à chaque fois qu'il reçoit une requête. Ce thread traite la requête et disparaît une fois que la requête est traitée.

Question 1.2

Se positionner dans le répertoire parent de Q1.
Taper la commande : cp  -R  Q1  Q2
Se positionner dans le répertoire Q2 qui vient d'être créé.

Dans ce répertoire Q2 (qui reprend le code de la question Q1), adapter le serveur de sorte qu'il forke 3 threads :
  • Chaque thread ouvre le fichier, se met dans le "pool" de threads en attente et attend une requête du processus distributeur.
  • Sur réception d'une requête, le serveur retire le premier thread du "pool" et lui fait suivre la requête :
    • le thread cherche le "M. et Mme" dans le fichier ;
    • il répond au client ;
    • il se remet dans le "pool" ;
    • il attend une requête du processus distributeur.
Le "pool" de threads peut être implanté à l'aide :
  • d'un tube. Les threads sont en attente de lecture sur ce tube. Quand le serveur veut leur faire suivre une requête, il écrit sur ce tube : l'un des threads lit la requête sur le tube et la traite.
  • d'une file de message (même principe que le tube).
  • d'un tableau circulaire de requêtes géré via le paradigme producteur/consommateur, le serveur étant le producteur et les threads étant les consommateurs.
  • de 4 tubes, 3 tubes serveur-thread (1 par thread) et 1 tube threads-serveur. Quand un thread est prêt à recevoir une requête, il écrit le descripteur de fichier de son tube serveur-thread dans le tube threads-serveur. Il se met ensuite en attente de lecture sur ce tube parent-thread. Quand le serveur reçoit une requête, il lit un descripteur de fichier de tube parent-thread dans le tube threads-parent, puis écrit la requête dans ce tube parent-thread. Le thread lit la requête et la traite.
  • toute solution que vous imaginerez et qui fonctionne !

Question 1.3

Se positionner dans le répertoire parent de Q1.
Taper la commande : cp  -R  Q1  Q3
Se positionner dans le répertoire Q3 qui vient d'être créé.

Dans ce répertoire Q3 (qui reprend le code de la question Q1), programmer le serveur de sorte qu'il forke 26 threads (chacun étant chargé des "M. et Mme" commençant par une certaine lettre de l'alphabet) :
  • Chaque thread cherche, dans le fichier, la première et la dernière ligne commençant par sa lettre.
  • Sur réception d'une requête, le processus distributeur fait suivre la requête à le thread correspondant à la 1-ère lettre du "M. et Mme" :
    • le thread ne cherche que dans les lignes qui le concernent ;
    • il répond au client  ;
    • il attend une nouvelle requête du processus distributeur.

Question 4 (non corrigée)

Reprendre le code réalisé à la question 1 avec les contraintes suivantes :
  • Le serveur peut forker au maximum 3 threads pour le traitement des requêtes.
  • Chacun de ces threads transmet à un thread spécial (le "factureur") un "ticket de facturation" (contenant le pid du processus demandeur et le nom de M. et Mme demandé). Cet thread spécial écrit ensuite le ticket dans un fichier texte. La transmission d'information entre les threads traitant les requêtes et le "factureur" sera d'abord faite avec un pipe, puis avec une zone de mémoire partagée.

Exercice 2

Repérer les différentes architectures client-serveur mises en oeuvre dans l'exercice 1.

Exercice 3 : M. et Mme... mais avec des enfants

Cet exercice reprend les questions de l'exercice 1, mais en utilisant des enfants au lieu de threads.

Préparation

Se placer dans un répertoire de travail
Vérifier que le tar ci-dessous ne risque pas d'écraser l'éventuel travail que vous avez fait sur le répertoire Q1 lors de l'exercice 1.
tar xvfz q1.tgz
cd Q1

Question 3.1

Même fonctionnement qu'à la question 1.1 de l'exercice 1, sauf que dans cette question 3.1, vous devez programmer le serveur de sorte qu'il forke un enfant à chaque fois qu'il reçoit une requête. Cet enfant traite la requête et disparaît une fois que la requête est traitée.

Question 3.2

Se positionner dans le répertoire parent de Q1.
Taper la commande : cp  -R  Q1  Q2
Se positionner dans le répertoire Q2 qui vient d'être créé.

Même fonctionnement qu'à la question 1.2 de l'exercice 1, sauf que dans cette question 3.2, vous devez travailler avec des processus enfants et pas des threads.

Question 1.3

Se positionner dans le répertoire parent de Q1.
Taper la commande : cp  -R  Q1  Q3
Se positionner dans le répertoire Q3 qui vient d'être créé.

Même fonctionnement qu'à la question 1.3 de l'exercice 1, sauf que dans cette question 3.3, vous devez travailler avec des processus enfants et pas des threads.







Page mise à jour le 17 mai 2016