Road Sockets

Le répertoire de ce TP dans votre dépôt GIT s’appellera "TPRoadSocket".

L’objectif de ce TP est de faire passer des voitures d’une machine à l’autre via des sockets. Idéalement, une voiture devra pouvoir traverser toutes les machines de la salle de TP. Pour cela vous allez devoir connecter et synchroniser des instances du programme qui fait passer des voitures sur la route.

Vous pouvez télécharger une version PDF de ce sujet.

Attendu

Vous avez deux séances pour ce TP.

Une troisième séance, non notée, sera consacrée à la mise en commun des solutions pour faire passer une voiture de machine en machine, idéalement en boucle dans la salle de TP. Cette séance sera également l’occasion de poser toutes les questions que vous auriez sur la matière.

Fichiers attendus:
  • OS_Nom1_Nom2/

    • TPRoadSocket/

      • .gitignore (avec tout ce qui n’est pas attendu)

      • Makefile

      • RoadSocketIn.c

      • RoadSocketInOut.c

Mise en place

  • Récupérez le répertorie Reseau situé dans le répertoire /users/but/info/Public/Systeme/. Ce répertoire contient un module Reseau (constitué des deux fichiers Reseau.c et Reseau.h) contenant des fonctions qui simplifient l’ouverture de connexions réseaux en mode client ou en mode serveur. La documentation de ces fonctions est dans les fichiers Reseau.h et Reseau.c.

  • Pour démarrer, récupérez un programme fonctionnel du TP “TPThreadRoad” que vous avez réalisé plus tôt dans l’année. Si votre TP n’était pas fonctionnel, vous pouvez récupérer le programme d’un autre binôme pour démarrer sur une bonne base.

Il est préférable de partir d’un programme avec la route à double sens, sans mutex ni sémaphores, pour simplifier le travail sur les sockets.

Comme pour le TP précédent, référez-vous à la page dédiée à la bibliothèque libroad pour la mise en place et la documentation.

1. Création d’une voiture sur message socket

Vous répondrez à cette question dans un fichier RoadSocketIn.c.

L’objectif ici est de créer une nouvelle voiture lors de la réception d’un message sur un socket.

1.1. Prise en compte des arguments de la ligne de commande

Vous ajouterez la prise en compte des arguments de la ligne de commande afin de pouvoir préciser :

  • le numéro de port d’écoute pour le serveur,

  • le numéro de port de connexion pour le client.

Pour rappel, vous aurez besoin des arguments argc et argv de la fonction main.

La fonction C “atoi” vous sera aussi très utile pour la gestion des numéros de port.

Cela facilitera vos tests qui peuvent être perturbés par des échecs de connexion sur des ports utilisés auparavant. Si vos connexions échouent sans raison, tentez de changer de numéro de port.

1.2. Création d’un serveur socket

Ajouter à votre programme de base qui fait passer des voitures, la création d’un serveur qui écoute sur un port prédéfini. Encore une fois, partez d’un programme simple avec la route à double sens, un thread de création de voitures et un thread par voiture pour les faire avancer. N’utilisez pas la version avec sémaphores et mutex.

Toutes les informations nécessaires à la création d’un serveur socket sont dans le fichier "Reseau.h" que vous devez avoir copié dans votre répertoire de TP.

1.3. Tests avec "netcat" (nc)

Pour tester la réception d’un message par votre programme, utilisez la commande "nc" (pour netcat).

netcat permet de créer simplement un serveur ou un client socket:

1.3.1. Serveur socket avec nc

Pour créer un serveur socket avec netcat :

$ nc -v -l -p 4321

-v : verbose

-l : listen

-p : port number

1.3.2. Client socket avec nc

Pour créer un client socket avec netcat :

$ nc -v localhost 4321

Lancez les deux commandes précédentes dans deux terminaux différents, en commençant par le serveur.

Constatez que le texte tapé dans le terminal du client est transmis au serveur.

1.4. Création d’une voiture avec netcat

Utilisez netcat pour envoyer un message à votre programme, qui joue donc le rôle d’un serveur. Vérifiez qu’une voiture est bien créée.

L’avancement des voitures doit rester dans un thread.

2. Envoi d’un message sur sortie d’une voiture

Vous répondrez à cette question dans un fichier RoadSocketInOut.c.

2.1. Création d’un client socket

Ajoutez au code précédent la création d’un client socket et sa connection à un serveur sur un port dont le numéro sera passé en argument de la ligne de commande.

2.2. Envoi du message sur sortie voiture

Faites en sorte que lorsqu’une voiture à terminé de traverser la route, un message soit envoyé sur la socket cliente que vous venez d’ajouter à votre programme.

2.3. Tests

Là encore vous pouvez utiliser nc pour tester la nouvelle fonctionnalité. Par exemple, pour lancer un serveur écoutant sur le port 4242, vous pouvez lancer la commande :

$ nc -v -l -p 4242

Une fois cette commande lancée et un client connecté, vous verrez le texte reçu sur la socket apparaître à l’écran.

Vérifiez que vous recevez bien un message lorsqu’une voiture termine sa traversée.

La difficulté de cette question est de ne pas bloquer tout le programme sur l’attente d’une connexion entrante ou sortante. Il vous faudra donc mettre ces attentes dans des threads.

Il est fortement recommandé de faire des schémas à ce stade pour clarifier les choses.

2.4. Deux programmes en local

Lancez deux instances de votre programme (dans deux terminaux différents) avec des ports compatibles : le client de la première instance doit se connecter au serveur de la deuxième.

Vérifiez qu’une voiture se créé dans la première instance sur réception d’un message socket puis qu’elle continue dans la deuxième instance une fois la première traversée terminée.

2.5. Boucle (bonus)

Si vos programmes fonctionnent correctement et qu’il vous reste du temps, une extension consiste à configurer les ports de vos programmes afin de faire passer une voiture en boucle sur deux instances (ou plus) de votre programme. Démarrez la boucle en envoyant un message via nc à votre serveur. Vous devriez voir une voiture "boucler".

Vous constaterez qu’il est possible de connecter plusieurs clients à un même serveur.

3. Challenge collectif

Pour terminer les TPs, vous allez essayer lors de cette dernière séance, de faire boucler une voiture autour de la salle de TP. Cette étape est collective et non notée.

3.1. Passage d’une machine à l’autre - Boucle dans la salle

Ajoutez la gestion d’un argument supplémentaire : le nom de la machine à laquelle le client doit se connecter.

Testez le passage d’une voiture d’une machine à une autre.

L’objectif collectif final est de réussir à faire faire le tour de la salle de TP à une voiture (ou plus).

Les plus courageux géreront un autre sens de circulation pour les voitures.

En espérant que vous ne voyez pas trop de voitures passer dans votre sommeil…​