AlgoC

Sujets de travaux pratiques d'Algorithmes et C appliqués aux Systèmes Numériques

View on GitHub

Année: 2022-2023

Projet

L’objectif du projet est de créer un environnement client-serveur dédié à l’analyse et à la gestion d’images, y compris leurs métadonnées. Une caractéristique distinctive de notre approche réside dans notre gestion des données. Contrairement aux méthodes conventionnelles d’applications client-serveur, notre système n’envoie pas les images brutes au serveur pour analyse. Au contraire, nous optons pour une analyse d’image côté client, garantissant la confidentialité des données, puis nous transmettons uniquement des rapports de synthèse pertinents au serveur central. Cette approche assure un équilibre optimal entre l’efficacité de l’analyse d’image et le respect de la vie privée des utilisateurs.

Client-Serveur

Un environnement client-serveur établit un mode de communication essentiel sur un réseau entre différents programmes. Le serveur, l’un de ces programmes, est chargé de répondre aux requêtes émanant d’autres programmes, désignés comme clients. À titre d’illustration, ce mécanisme permet à un client d’envoyer un message au serveur, qui le reçoit et renvoie une réponse. De même, un client peut transmettre un opérateur ainsi qu’un ou deux numéros au serveur, lequel effectue le calcul correspondant avant de renvoyer le résultat.

Référence : https://fr.wikipedia.org/wiki/Client-serveur

Dans le cadre de ce projet, le serveur maintient une connaissance limitée des informations pour chaque client. Ces informations incluent :

  1. Nom de la machine cliente: Le serveur identifie chaque client par le nom de sa machine, assurant une gestion claire des connexions.
  2. Balises (hashtags) d’image distinctes sur l’ordinateur client: Pour chaque client, le serveur conserve une liste des balises d’image distinctes présentes sur l’ordinateur, telles que “chats,” “chiens,” etc. Cela facilite la catégorisation et l’indexation des images.
  3. Couleurs prédominantes des images sur la machine cliente: Le serveur enregistre également les couleurs prédominantes présentes dans les images de l’ordinateur client, en utilisant des codes de couleurs, par exemple, “#2020DE,” “#FF3E23,” etc. Cette information peut être utile pour des tâches telles que la recherche d’images similaires.

Il y a cinq tâches dans ce projet.

Environnement de programmation:

Algorithmes et structure de données: par exemple, liste, pile, file, graphes

Tâche 1.

Dans notre première tâche, votre mission consiste à envoyer différents types de messages.

  1. Le client envoie son nom et le serveur renvoie le même nom, en guise d'accusé de réception.
  2. Un simple message envoyé par le client, auquel le serveur renvoie une réponse.
  3. Le client envoie deux numéros et un opérateur mathématique et le serveur répond le résultat de l'opération.
  4. Le client envoie N couleurs et le serveur les enregistre dans un fichier.
  5. Le client envoie N balises et le serveur les enregistre dans un fichier.

a. message

Pour simuler un environnement client-serveur, on va utiliser une seule machine en lançant deux terminaux. Sur un des deux terminaux exécutez le code du serveur. Sur l’autre, exécutez le code du client.

Téléchargez les fichiers suivants à partir d’e-campus : client.h, client.c, serveur.h, serveur.c, Makefile. Lisez bien tous les fichiers. Exécutez

` $ make `

et voyez les fichiers exécutables qui sont créés.

Ouvrez deux terminaux. Sur le premier terminal, exécutez

` ./serveur `

et sur le second terminal

` ./client `

Entrez un message et voyez les affichages sur les deux terminaux.

Modifiez la fonction recois_envoie_message (serveur.c). Quand le serveur reçoit un message, il demande à l’utilisateur de saisir un message et envoie ce message au client. Testez votre code.

Attention: N’oubliez pas d’utiliser make (pour la compilation et la génération des fichiers exécutables).

b. nom

Vous avez remarqué les premiers caractères dans chaque message commencent par ‘message’ et suivi par :. Pour toutes les prochaines missions, nous devons remplacer "message" par "nom"/"calcul"/"couleurs". Votre prochain objectif est d'écrire une fonction envoie_nom_de_client(...) dans le fichier client.c (C'est à vous pour décider le nom) et une fonction renvoie_nom(...) dans le fichier serveur.c qui renvoie le nom.

Astuce : Vous pouvez utiliser la fonction gethostname(…) (unistd.h) pour obtenir le nom de votre machine. Ne demandez pas le nom de votre machine à l’utilisateur.

c. calcul

Votre prochaine mission consiste à effectuer des opérations mathématiques côté serveur. Modifiez les fichiers client.c et serveur.c pour prendre en charge des opérations mathématiques simples (+,-,*,...). Ajoutez une fonction envoie_operateur_numeros(...) dans le fichier client.c et recois_numeros_calcule(...) dans le fichier serveur.c. Le client envoie l’opérateur et un (ou deux) numéros et le serveur envoie le résultat. Par exemple, si le client envoie le message.

` calcule : + 23 45 `

Le serveur répond

` calcule : 68 `

Testez votre code avec des nombres à virgule flottante et des entiers.

d. couleurs

Votre prochaine mission dans cette tâche consiste à écrire une fonction envoie_couleurs(...) dans le fichier client.c et une fonction recois_couleurs(...) dans le fichier serveur.c. Le client envoie N couleurs (N<30) en utilisant le codage RGB (https://fr.wikipedia.org/wiki/Rouge_vert_bleu) et le serveur reçois ces couleurs et les enregistre dans un fichier.

par exemple, si le client veut envoyer 10 couleurs, il enverra le message suivant

` couleurs: 10, #0effeee,… `

e. balises

Votre dernière mission dans cette tâche consiste à écrire une fonction envoie_balises(...) dans le fichier client.c et une fonction recois_balises(...) dans le fichier serveur.c. Le client envoie N balises (N<30) et le serveur reçois ces balises et les enregistre dans un fichier.

par exemple, si le client veut envoyer 10 balises, il enverra le message suivant

` balises: 10, #nature, #arbre,… `

Tâche 2.

Pour cette tâche, notre objectif est d'utiliser le format d'image bmp et de communiquer entre le serveur et le client à l'aide du format de message JSON.

Modifiez les fichiers json.h et json.c.

Références:

  1. BMP : https://fr.wikipedia.org/wiki/Windows_bitmap
  2. JSON : https://fr.wikipedia.org/wiki/JavaScript_Object_Notation

a. Firefox

Téléchargez les fichiers suivants à partir d’e-campus : bmp.h,, client.h, couleur.h, json.h, operations.c, serveur.c, testes.c, validation.c, bmp.c, client.c, couleur.c, json.c, Makefile, operations.h, serveur.h, testes.h, validation.h

Téléchargez le dossier images. Les images proviennent de Wikimedia Commons et sont en format BMP.

Lisez bien les fichiers. bmp.c, bmp.h qui vous permettent d’analyser les images en format BMP.

Lancez la compilation avec

` $ make `

et voyez les fichiers exécutables qui sont créés. Ouvrez deux terminaux. Sur le premier terminal, exécutez

` ./serveur `

et sur le second terminal

` ./client chemin_d’une_image_bmp `

Le serveur reçois les dix premières couleurs de l’image analysé par le client et exécute une commande déjà existantes sur votre machine : firefox.

Les deux fichiers serveur.c et client.c sont initialement écris pour travailler avec dix premières couleurs. Modifiez les deux fichiers de manière à ce que ce nombre de couleurs (toujours <=30) soit saisi par l’utilisateur. Testez votre code. N’oubliez pas d’utiliser make.

b. JSON

Nous avons utilisé les messages très simples entre client et serveur

` message: bonjour `

par exemple

              calcule: + 23 45
              couleurs: 10, #0effeee,...

Sans utiliser les bibliothèques externes, modifiez le code client.c et serveur.c et ajoutez de nouvelles fonctions pour travailler avec le format de messages JSON. Par exemple,

              {
                "code" : "message",
                "valeurs" : [ "bonjour"]
              }
              {
                "code" : "calcule",
                "valeurs" : [ "+", "23", "45" ]
              }
              {
                "code" : "couleurs",
                "valeurs" : [ 10, "#0effeee", "#0effe23", ...]
              }
              {
                "code" : "balises",
                "valeurs" : [ 10, "#nature", "#arbre", ...]
              }

Tâche 3.

Pour cette tâche, notre objectif est de nous assurer que le transfert des messages entre le client et le serveur respecte le format JSON et le protocole de communication.

Modifiez les fichiers validation.h, validation.c json.h et json.c.

Références:

  1. http://json.org/json-fr.html: Site officiel de JSON
  2. https://jsonlint.com/: JSONLint- The JSON Validator
  3. JSON : https://fr.wikipedia.org/wiki/JavaScript_Object_Notation

a. Validation des messages JSON

Sans utiliser les bibliothèques externes, créez un fichier C validateur.c et ajoutez de nouvelles fonctions pour valider les messages JSON.

Par exemple, les messages suivantes sont valides. Vous voyez que nous n'utilisons pas de guillemets pour les nombres, mais nous utilisons des guillemets pour les chaînes de caractères.

Remarquez que pour les opérations “calcule”/”balises”, nous avons maintenant ajouté le nombre de couleurs/tags dans la liste “valeurs”.

              {
                "code" : "message",
                "valeurs" : [ "bonjour"]
              }
              {
                "code" : "calcule",
                "valeurs" : [ "+", 23, 45 ]
              }
              {
                "code" : "couleurs",
                "valeurs" : [ 10, "#0effeee", "#0effe23", ...]
              }
              {
                "code" : "balises",
                "valeurs" : [ 10, "#nature", "#arbre", ...]
              }

Mais, la message suivante n'est pas valide parce que les valeurs 'message' et 'bonjour' ne figurent pas entre les guillemets.

                "code" : message,
                "valeurs" : [ bonjour]
              }

Vous pouvez tester la validité des messages JSON à l'aide du site en ligne https://jsonlint.com

Modifiez le code client.c et serveur.c et intégrez les nouvelles fonctions de validation pour que le serveur et le client reçoivent uniquement des messages JSON valides.

b. Validation du protocole de communication

Nous avons seulement autorisé quatre opérations. Notre prochain objectif est de nous assurer que la demande envoyée par le client et la réponse envoyée par le serveur respectent le protocole et que nous n'acceptons aucune autre opération.

Voir les exemples donnés ci-dessous. Votre prochain objectif consiste à ajouter des fonctions dans le fichier validateur.c permettant de vérifier que chaque opération ne contient que les valeurs autorisées.

1. message

Exemple de requête envoyé par le client

                "code" : "message",
                "valeurs" : [ "bonjour"]
              }

Exemple de réponse envoyé par le serveur

                "code" : "message",
                "valeurs" : [ "bonjour"]
              }

2. nom

Exemple de requête envoyé par le client


              {
                "code" : "nom",
                "valeurs" : [ "neptune"]
              }             

Exemple de réponse envoyé par le serveur


              {
                "code" : "nom",
                "valeurs" : [ "neptune"]
              }             

3. calcul

Exemple de requête envoyé par le client


              {
                "code" : "calcule",
                "valeurs" : [ "+", 23, 45 ]
              }             

Exemple de réponse envoyé par le serveur

              {
                "code" : "calcule",
                "valeurs" : [ 68 ]
              }             

4. couleurs

Exemple de requête envoyé par le client


              {
                "code" : "couleurs",
                "valeurs" : [ 10, "#0effeee", "#0effe23", ...]
              }             

Exemple de réponse envoyé par le serveur


              {
                "code" : "couleurs",
                "valeurs" : [ "enregistré"]
              }             

5. balises

Exemple de requête envoyé par le client


              {
                "code" : "balises",
                "valeurs" : [ 10, "#nature", "#arbre", ...]
              }             

Exemple de réponse envoyé par le serveur


              {
                "code" : "balises",
                "valeurs" : [ "enregistré"]
              }             

Tâche 4.

a. Opérations

Votre tâche suivante consiste à implémenter les fonctionnalités suivantes sur le serveur.

Jusqu'à présent, vous avez envoyé des opérations simples au serveur: +, - etc. Modifiez le code client pour envoyer une liste de nombres et un calcul d’opérations avec plus de possibilités: moyenne, minimum, maximum, écart type.

Le client et le serveur doivent envoyer des valeurs JSON valides. Modifiez les fichiers operations.h, operations.c, validation.h, validation.c json.h et json.c.

Exemple de requête envoyé par le client


              {
                "code" : "calcule",
                "valeurs" : [ "minimum", 23, 45, 34 ]
              }             

Exemple de réponse envoyé par le serveur


              {
                "code" : "calcule",
                "valeurs" : [ 23 ]
              }             

Tâche 5.

Plusieurs clients

Votre objectif final pour ce projet est de créer une plate-forme multi-client. Jusqu'à maintenant, vous avez toujours un client et un serveur à la fois. Mais maintenant, nous voulons que plusieurs clients puissent communiquer avec votre serveur à la fois. Modifier votre code serveur, afin qu'il puisse accepter plusieurs requêtes client à la fois.

En utilisant le code écrit dans les tâches précédentes, écrire un code afin que chaque client informe le serveur des informations suivantes et que le serveur les enregistre.

Enfin, écrivez des tests fonctionnels et unitaires pour vérifier si

Fichiers

bmp.c client.c couleur.c json.c operations.c serveur.c testes.c validation.c bmp.h client.h couleur.h json.h operations.h serveur.h testes.h validation.h Makefile