Vous êtes sur la page 1sur 116

Dr.A.

Adouane 1
 L’échange de message ou communication interprocessus est utilisé
pour synchroniser les processus entre eux

 Il est important de comprendre le principe de partage de variable,


nous étudiants pour cela les modèles:

 Lecteur/Rédacteur

 Producteur/Consommateur

 Dîner des philosophes


 Lecteurs-Rédacteurs:
 On considère deux processus communiquant par un fichier

 Un fichier ou une zone de mémoire commune est accédée en


lecture et en écriture

 Deux types de processus:


◦ Des processus lecteurs
◦ Des processus rédacteurs.
 Deux objectifs doivent être atteints:
 Les écritures ne doivent pas avoir lieu en même temps
 les lecteurs ne doivent pas lire une information en cours de
modification

 il faut donc, à un instant donné:


 soit une seule écriture en cours
 soit une ou plusieurs lectures en cours
 Le rédacteur
 un rédacteur accède toujours seul au fichier ou à la zone de
mémoire commune
 Il exclut donc les autres rédacteurs ainsi que tous les lecteurs.
 Le lecteur:

 Un lecteur exclut les rédacteurs mais pas les autres lecteurs.

 Seul le premier lecteur doit donc s’assurer qu’il n’y a pas


d’accès en écriture en cours

 Seul le dernier lecteur doit libérer la ressource et réveiller un


éventuel rédacteur.
 Il faut compter le nombre de lecteurs qui accèdent au fichier ou à
la zone de mémoire partagée

 une variable nl, initialisée à 0 est accédée en concurrence par tous


les lecteurs qui vont soit incrémenter cette variable (un lecteur de
plus), soit la décrémenter (un lecteur de moins)

 il faut que nl soit accédée en exclusion mutuelle par tous les


lecteurs.

 L’accès à la variable est donc gardé par un sémaphore mutex


initialisé à 1.
 On considère deux processus communiquant par un tampon
de n cases

 le producteur qui produit et dépose les messages depuis la


case 0 jusqu’à la case n – 1, puis revient à la case 0

 le consommateur prélève les messages depuis la case 0


jusqu’à la case n – 1, puis revient à la case 0.
 Le processus producteur et le processus consommateur sont
totalement indépendants, pour qu’aucun message ne soit
perdu, les trois règles suivantes doivent être respectées :

 le producteur ne doit pas produire si le tampon est plein;

 le consommateur ne doit pas faire de retrait si le tampon est


vide;

 le producteur et le consommateur ne doivent jamais travailler


dans une même case
 Deux types de ressources distinctes peuvent être mis en avant

 Le producteur consomme des cases vides et fournit des cases


pleines;

 Le consommateur consomme des cases pleines et fournit des


cases vides.

 On a des ressources cases vides et des ressources cases


pleines
 Le problème va apparaitre lorsque le producteur va essayer de
remplir une case pleine

 La solution est de mettre le producteur en pause ( sommeil), il


sera ensuite réveillé quand le consommateur aura vider le
tampon

 De la même manière si le consommateur essaye de vider une


case vide, il sera mis en pause en attente d’un réveil une fois
le tampon rempli par le producteur
 Problème d’allocation de ressources critiques

 On associe un sémaphore à chacune des ressources


identifiées, initialisé au nombre de cases respectivement vides
ou pleines initialement disponibles (n et 0)

 les deux sémaphores vide initialisé à n et plein initialisé à 0


 Le producteur signale:
 une case vide par une opération P(vide)
 Un remplissage de case par une opération V(plein)
 Le consommateur signale :
 une case pleine par une opération P(plein)
 Le vidage d’une case par une opération V(vide)
 Exemple : un ensemble de producteurs, un consommateur et
une file F, synchroniser l'accès à une imprimante

 Les machines qui envoie les requêtes d’impression forme les


producteur

 Le spooler d’impression sera le consommateur


 Le code exécuté par les producteurs est le suivant:

 Créer un document D
 verrouiller F
 ajouter D à la fin de la file F
 déverrouiller F
 envoyer un signal au consommateur
 Le code exécuté par le consommateur

 répéter
 attendre un signal de F
 tant que F n'est pas vide
 pour chaque élément E de F
 verrouiller F
 imprimer E
 supprimer E de F
 déverrouiller F
 fin pour
 fin tant que
 attendre un signal d'un producteur
 fin répéter
 Le code exécuté par le consommateur

 répéter
 attendre un signal de F
 tant que F n'est pas vide
 pour chaque élément E de F
 verrouiller F
 imprimer E
 supprimer E de F
 déverrouiller F
 fin pour
 fin tant que
 attendre un signal d'un producteur
 fin répéter
 monitor ProducerConsumer
 condition full , empty ;
 integer count ;
 procedure insert (item : integer );
 begin
 if count = N then wait (full );
 insert_item (item );
 count := count + 1:
 if count = 1 then signal (empty )
 end ;
 function remove : integer ;
 begin
 if count = 0 then wait (empty);
 remove = remove_item ;
 count := count - 1;
 if count = N - 1 then signal (full )
 end ;
 count := 0;
 end monitor ;
 procedure producer ;
 begin
 while true do
 begin
 item = produce_item ;
 ProducerConsumer .insert (item )
 end
 end ;
 procedure consumer ;
 begin
 while true do
 begin
 item = ProducerConsumer .remove ;
 consume_item (item )
 end
 end ;
 Le problème du diner des pholosophes a été introduit et traité
par Dijkstra

 Ce problème illustre un cas de synchronisation applicable à


beaucoup de situation de partage de ressource

 Les philosophes représente les taches ou processus dans un


système
 Problème :

 Cinque philosophes autour d’une table pour diner

 Chacun des philosophes a devant lui un plat de nouille

 À gauche de chaque plat se trouve une baguette

 Pour manger il faut les deux baguettes autour du bol


 Chaque philosophe peut se trouver dans les cas suivant :

 Penser pendant un temps indéterminé, il n’a pas besoin de


baguettes

 Être affamé, il demande à manger mais manque de baguettes


(pendant un temps déterminé et fini sinon il y a famine)

 Manger pendant un temps déterminé et fini


 Ressource partagé = baguette, le philosophe prend les deux
baguette dans l’ordre gauche>droite

 Seul deux philosophes peuvent manger en même temps

 Les deux qui mange ne sont jamais l’un à côté de l’autre

 Le philosophe qui fini de manger pause les baguettes dans le


même ordre qu’il les prend
 Quand un philosophe a faim, il va se mettre dans l'état
« affamé » et attendre que les baguettes soient libres

 si il n'arrive pas à s'emparer d'une baguettes, il reste affamé


pendant un temps déterminé, en attendant de renouveler sa
tentative
 Philosophe Pi

 TantQue VRAI faire


 /* penser */
 prendre_couverts(i)
 /* manger */
 poser_couverts(i)
 FinTantQue
 procedure prendre_couverts(i : entier)
 debut
 P(mut) on s'assure l'usage exclusif de état
 etat[i] affame on se déclare « affamé »
 si(etat[i-1]!= mange) et (etat[i+1]!=mange) alors si les voisins ne mangent
pas
 etat[i] mange … on peut manger !
 V(philo[i]) philo[i] est levé pr ne pas être bloqué ensuite
 finsi
 V(mut) l'accès à etat est libéré
 P(philo[i]) si les voisins ne mangent pas, l'opération P est
non bloquante (philo[i] vaut 1), sinon : mise en
sommeil.
 fin
 procedure poser_couverts(i : entier)
 debut
 P(mut) on s'assure l'usage exclusif de etat
 etat[i] pense on déclare qu'on ne mange plus
 si (etat[i-1]=affame) et etat[i-2]!=mange) alors
Si le voisin de droite veut manger et si sa
baguette droite est libre...
 etat[i-1] mange … il peut manger ...
 V(philo[i-1]) … on le réveille (il est endormi sur P(philo))
 finsi
 si (etat[i+1]=affame) et (etat[i+2]!=mange) alors
Même processus pour le voisin de gauche
 etat[i+1] mange
 V(philo[i+1])
 finsi
 V(mut) on libère l'accès à etat
 fin
 MONITEUR Philo
 VARIABLES etat[5] // dénote l'état des philosophes
 CONDITIONS C[5] : tableau de conditions // une condition par philosophe
 procedure prendre_couverts(i : entier)
 debut
 etat[i] affame on se déclare « affamé »
 si(etat[i-1]!= mange) et (etat[i+1]!=mange) alors
si les voisins ne mangent pas...
 etat[i] mange … on peut manger !
 sinon
 wait(C[i]) sinon on s'endort
 finsi
 fin
 procedure poser_couverts(i : entier)
 Début
 etat[i] pense on déclare qu'on ne mange plus
 si (etat[i-1]=affame) et etat[i-2]!=mange) alors
Si le voisin de droite veut manger et
si sa
baguette droite est libre...
 etat[i-1] mange … il peut manger ...
 signal(C[i1]) … on le réveille (il est endormi sur wait)
 finsi
 si (etat[i+1]=affame) et (etat[i+2]!=mange) alors
Même processus pour le voisin de gauche
 etat[i+1] mange
 signal(C[i+1])
 finsi
 Fin
 Début Initialisation
 Initialiser le tableau etat à « pense »
 fin
 Une solution pour la communication inter-processus et
l’échange de messages

 Utilisation de deux prémitives : Send et Receive

 Ces deux primitives sont des appels système et peuvent être


facilement rajouter à des bibliothèque
 Un exemple est :
◦ Send ( destination, &message)

◦ Receive ( source, &message)

 Le premier appel envoie un message vers une destination

 Le deuxième appel va recevoir le message

 Si pas de message le récepteur se bloque en attente d’un


message
 Les systèmes d’échange de message constituent un défis de
conception plus important que les sémaphores ou les
moniteurs

 Si les processus sont sur des ordinateurs différents les


messages peuvent être perdu dans le réseau par exemple

 On utilise donc le système d’accusé de réception


(acknowledgement)
 La perte d’un message doit être corrigé par sa retransmission

 Si l’accusé de réception est perdu, le message sera renvoyé, et


sera reçu en double, il est nécessaire de corriger ce problème

 Un numéro de message est rajouter, si le même numéro est


reçu, alors le deuxième est ignoré

 Beaucoup d’étude sont réalisé dans ce sens pour fiabiliser les


communications dans les réseaux
 Le système de message doit également prendre en compte
une nomination correcte des processus

 Il est nécessaire d’avoir une distinction parfaite des processus


pour les appels Send et Receive

 L’echange de message pause aussi un problème de sécurité,


une authentification est nécessaire pour garantir que le
message ne vient pas d’un Hacker
 Producteur/consommateur avec échange de message:

 Dans le code on suppose que les messages non reçus sont


sauvegardé dans un tampon

 N messages de même tailles doivent être envoyés

 Le consommateur envoie N messages vides au producteur

 Le producteur remplie les messages vides quand il a un élément à


envoyer au consommateur, il renvoie donc des messages pleins
 Le nombre de message est constant dans le système

 Si tous les messages sont remplis le producteur se bloque

 Si tous les messages sont vides c’est le consommateur qui se


bloque
 Un autre schéma système qui implémente le
producteur/consommateur est la Mailbox ou Boîte au lettre

 Lorsqu’on utilise une mailbox les paramètres d’adressage des


appels send et receive déclarent la mailbox

 Les deux processus envoient leurs message respectives à des


mailbox
 Le producteur et le consommateur doivent crées des mailbox
pour contenir les N messages

 Le producteur va envoyer des messages pleins à la mailbox du


consommateur

 Le consommateur de son coté va envoyer ses messages vides


au producteur
 Si une des mailbox est pleine le processus propriétaire est mis
en pause

 Avec ce système la mise en mèmoire des messages est claire,


chaque processus aura les messages qui lui sont adressé dans
sa mailbox
 Il est possible de crée une mailbox avec capacité nul

 l'envoi de message ne peut avoir lieu que lorsque le receveur


est prêt à recevoir le message

 Si on fait un send avant que le receive ne soit fait le processus


émetteur est bloqué jusqu’à se que le receive soit appelé
 On dit alors qu'il y a communication synchrone entre le
producteur et le consommateur

 Après le retour de la primitive d'envoi, le producteur a la


garantie que le consommateur a effectivement reçu le
message

 On appel cette stratégie rendez-vous, elle est plus facile à


mettre en œuvre mais a le problème d’inter-blocage possible
!
 Les tubes de communication son des tuyaux (en anglais pipe)

 Ils présentent une autres méthode de modélisation du


producteur/consommateur

 Pour un processus, un tube se présente comme deux flots:

◦ l'un ouvert en écriture (pour le producteur)

◦ l'autre ouvert en lecture (pour le consommateur)


 Lorsqu'un processus crée un tube, le système lui retourne les
deux flots.

 Si ce processus crée ensuite un processus fils, celui-ci obtient


une copie des flots ouverts, lui permettant ainsi de lire ou
d'écrire dans le tube

 Seuls les processus situés dans la sous-arborescence du père


ainsi que le père peuvent communiquer par un tube
 Le problème est qu’on crée le tube dans un seul processus, et
un autre processus ne peut pas deviner les valeurs du tableau
descripteur

 il faut appeler la fonction pipe avant d’appeler la fonction fork

 Ensuite, le processus père et le processus fils auront les


mêmes descripteurs de tubes, et pourront donc communiquer
entre eux
 un tube ne permet de communiquer que dans un seul sens.

 Si on souhaite que les processus communiquent dans les


deux sens, il faut créer deux pipes

 Pour écrire et lire un pipe on utilise :

◦ Write

◦ Read
 Les tubes ne conservent pas la structuration des messages qui
sont envoyés par le producteur

 Producteur et consommateur participent tous les deux à cette


structuration

 Dan l’exemple, le consommateur lit depuis le tube les octets 2


par 2 pour retrouver la structure des messages émis par le
producteur
 On crée un tube par un appel à la fonction pipe, déclarée dans
unistd.h

 On le déclare avec : int pipe(int descripteur[2]);

 La fonction renvoie 0 si elle réussit, elle crée alors un nouveau


tube avec le tableau descripteur[2] passé en paramettre
 La fonction pipe remplit le tableau descripteur passé en
paramètre, avec :

 descripteur[0] désigne la sortie du tube (dans laquelle on peut


lire des données) ;

 descripteur[1] désigne l’entrée du tube (dans laquelle on peut


écrire des données) ;
 Fonctionnement :

 Le processus qui veut écrire va envoyer les données sur


descripteur[1]

 Le processus lecteur va pour sa part attendre les données sur


descripteur[0]
 la fonction write :
 ssize_t write(int descripteur1, const void *bloc, size_t taille);

 Le descripteur doit correspondre à l’entrée d’un tube.

 La taille est le nombre d’octets qu’on souhaite écrire

 le bloc est un pointeur vers la mémoire contenant ces octets.


 la fonction read:
 ssize_t read(int descripteur0, void *bloc, size_t taille);

 Le descripteur doit correspondre à la sortie d’un tube

 le bloc pointe vers la mémoire destinée à recevoir les octets

 la taille donne le nombre d’octets qu’on souhaite lire


 La fonction renvoie le nombre d’octets effectivement lus.

 Si cette valeur est inférieure à taille, c’est qu’une erreur s’est


produite en cours de lecture

 Un buffer de taille fixe est utilisé, cette taille doit être la


même en lecture et en écriture
 Exemple d’un processus père qui crée un fls pour faire
ensemble un travail avec échange de variable :

 Processus père va envoyer (val1) vers le Processus fils

 Processus fils va envoyer (val2) vers le Processus père

 Père et le fils afficheront les informations reçues


 #include "stdio.h"
 #include "unistd.h"
 #include "stdlib.h"

 int fd1[2]; // Descripteurs : fd1[0] Canal de Lecture / fd1[1] Canal Ecriture


 int fd2[2];
 int main(){
 pid_t pid;
 int val1, val2;
 pipe(fd1);
 pipe(fd2);
Avant le fork()
PROCESSUS
PERE

fd1 0 1

fd2 0 1 pipe1
val1

val2

pipe2
 switch(pid=fork()){
 case 0: // fils
 close(fd1[1]; close(fd2[0]);
 scanf(‘’%d’’,&val2);
 write(fd2[1],&val2, sizeof(val2));
 printf(‘’Fils %d -> Pere %d : sent val %d
\n’’,getpid(),getppid(),val2);
 read(fd1[0],&val1,sizeof(val1));
 printf(‘’ Fils %d <- Père %d : rec val %d \n’’,getpid(),getppid(),val1);
 break;
Après le fork()
PROCESSUS PROCESSUS
PERE FILS

fd1 0 1 0 1 fd1

fd2 0 1 pipe1 0 1 fd2


val1
val1
val2
val2

pipe2
 default: // pere
 close(fd2[1]);
 close(fd1[0]);
 scanf(‘’%d’’,&val1);
 write(fd1[1],&val1, sizeof(val1));
 printf(‘’Pere %d -> Fils %d : sent val %d \n’’,getpid(),pid,val1);
 read(fd2[0],&val2,sizeof(val2));
 printf(‘’ Pere %d <- Fils %d : rec val %d \n’’,getpid(),pid,val2);
 wait(NULL);
 break;
 }
Après le fork()
PROCESSUS PROCESSUS
PERE FILS

Close
fd1 0 1 0 1 fd1

fd2 0 1 Write pipe1 0 1 fd2

Close

Read
pipe2
 switch(pid=fork()){
 case 0: // fils
 close(fd1[1]); // Je ne dois pas parler sur le Canal fd1
 close(fd2[0]); // Je ne dois pas écouter sur le Canal fd2
 scanf(‘’%d’’,&val2); // Demander à l’utilisateur de saisir une donnée
 write(fd2[1],&val2, sizeof(val2));//Je parle sur la chaine fd2 j’envoie val2 à papa
 printf(‘’Fils %d -> Pere %d : sent val %d \n’’,getpid(),getppid(),val2);
 read(fd1[0],&val1,sizeof(val1)); // J’écoute le canal fd1[0] et stock le contenu dans
// ma variable val1
 printf(‘’ Fils %d <- Père %d : rec val %d \n’’,getpid(),getppid(),val1);
 break;
PROCESSUS PROCESSUS
PERE FILS

Close Close

fd1 0 1 0 1 fd1

fd2 0 1 Write pipe1 Read 0 1 fd2

Close Close

Read
pipe2 Write
 Ce mode de communication désigne des communications à
travers un réseau entre des programmes

 Le client envoie des requêtes ou des demandes vers un


serveur. L’ordinateur sur lequel est installer le logiciel est
également appelé client

 Le serveur va attendre les demandes et y répond, on appel


aussi l’ordinateur qui porte ces logiciels serveur
 Les machines utilisées pour abriter les serveurs sont de
manière générale dédier, et ont des capacités de calcul et de
stockage bien supérieur aux ordinateurs personnels

 Un serveur peut prendre en charge plusieurs clients

 Les clients peuvent être des machines personnelles, des


smartphones ou des tablettes
 Il existe beaucoup de clients et serveurs selon l’utilisation et le
besoin :

 Un serveur Web publie des pages Web demandées par des


navigateurs Web

 Un serveur de messagerie électronique envoie du courriel à des


clients de messagerie

 Un serveur de fichiers permet de partager des fichiers sur un


réseau

 Un serveur de base de données permet de récupérer des données


stockées dans une base de données
 Caractéristiques d'un programme serveur :

 Il attend une connexion entrante sur un ou plusieurs ports


réseaux locaux

 À la connexion d'un client sur le port en écoute, il ouvre un


socket local au système d'exploitation ;

 À la suite de la connexion, le processus serveur communique


avec le client suivant le protocole prévu par la couche
application du modèle OSI.
 Caractéristiques d'un programme client :

 Il établit la connexion au serveur à destination d'un ou plusieurs ports


réseaux ;

 lorsque la connexion est acceptée par le serveur, il communique comme


le prévoit la couche application du modèle OSI.

 Le client et le serveur doivent bien sûr utiliser le même protocole de


communication au niveau de la couche transport du modèle OSI.

 On parle souvent d'un service pour désigner la fonctionnalité offerte par


un processus serveur.
 Repose sur une communication d’égal à égal entre les
applications

 Communication réalisée par dialogue entre processus deux à


deux

 Les processus ne sont pas identiques mais forment un


système coopératif se traduisant par un échange de données
 Avantages :

 Unicité de l'information : pour un site web dynamique par exemple, certaines


pages du site sont stockés dans une base de données sur le serveur. De cette
manière, les informations restent identiques. Chaque utilisateur accède aux
mêmes informations.

 Meilleure sécurité : Lors de la connexion un PC client ne voit que le serveur, et


non les autres PC clients. De même, les serveurs sont en général très sécurisés
contre les attaques de pirates.

 Meilleure fiabilité : En cas de panne, seul le serveur fait l'objet d'une réparation,
et non le PC client.

 Facilité d'évolution : Une architecture client/serveur est évolutive car il est très
facile de rajouter ou d'enlever des clients, et même des serveurs.
 Le client demande l’exécution d’un service

 Le serveur réalise le service

 Client et serveur sont généralement localisés sur deux


machines distinctes
 Communication par messages:

 Requête : paramètres d’appel, spécification du service requis


 Réponse : résultats, indicateur éventuel d’exécution ou
d’erreur
 Communication synchrone (dans le modèle de base) : le
client est bloqué en attente de la réponse
 Il existe différents architectures client-serveur:

 Architecture Peer to Peer

 Architecture à 2 niveaux

 Architecture à 3 niveaux

 Architecture à N niveaux
 Il en existe deux type

◦ Centralisé :un client se connecte à un serveur qui gère les partages,


bien que celles-ci transitent directement d'un utilisateur à l'autre.

◦ Décentralisé: les clients se connectent entre eux directement

 L’architecture est dite Peer to Peer (P2P) lorsque chaque


ordinateur connecté au réseau est susceptible de jouer tour à
tour le rôle de client et celui de serveur
 Ce type d'architecture ( 2-tier en anglais ) caractérise les
systèmes client-serveur où le poste client demande une
ressource au serveur qui la fournit à partir de ses propres
ressources

Cela signifie que le serveur ne fait


pas appel à une autre application
afin de fournir une partie du service.
 Dans cette architecture (3-tier en anglais), il existe un niveau
intermédiaire:

 Un client, c'est-à-dire l'ordinateur demandeur de ressources,


équipée d'une interface utilisateur (généralement un navigateur
web) chargée de la présentation ;

 Le serveur d'application (appelé également middleware), chargé de


fournir la ressource mais faisant appel à un autre serveur

 Le serveur de données, fournissant au serveur d'application les


données dont il a besoin.
 L'architecture à deux niveaux est une architecture dans
laquelle le serveur est polyvalent, il est capable de fournir
directement l'ensemble des ressources demandées par le
client

 Dans l'architecture à trois niveaux par contre, les applications


au niveau serveur sont délocalisées, c'est-à-dire que chaque
serveur est spécialisé dans une tâche (serveur web/serveur de
base de données…)
 L'architecture à trois niveaux permet :

 Une plus grande flexibilité/souplesse ;

 Une sécurité accrue car elle peut être définie


indépendamment pour chaque service, et à chaque niveau ;

 De meilleures performances, étant donné le partage des


tâches entre les différents serveurs.
 Dans l'architecture à 3 niveaux, Un serveur peut utiliser les
services d'un ou plusieurs autres serveurs afin de fournir son
propre service

 l'architecture peut être étendue sur un nombre de niveaux


plus important : On parle dans ce cas d'architecture à N
niveaux
 Client "léger" :

 Le poste client accède à une application située sur un


ordinateur dit "serveur" via une interface et un navigateur
Web.

 L'application fonctionne entièrement sur le serveur, le poste


client reçoit la réponse "toute faite" à la demande qu'il a
formulée. ("requête" )
 Client "lourd" :

 Le poste client doit comporter un système d'exploitation


capable d'exécuter en local une partie des traitements.

 le traitement de la réponse à la requête du client utilisateur va


mettre en œuvre un travail combiné entre l'ordinateur serveur
et le poste client
 Client "riche" :

 Une interface graphique plus évolué permet de mettre en


œuvre des fonctionnalités comparables à celles d'un client
"lourd".

 Les traitements sont effectués majoritairement sur le serveur ,


la réponse "semi-finie" étant envoyée au poste client , où le
client "riche" est capable de la finaliser et de la présenter.
 Un service est fourni sur un Port de communication identifié par un
numéro

 Certains numéros de Port (internationalement définis) identifient le


service quelque soit le site ex :

 le service FTP est offert sur les ports numéros 21 (contrôle) et 20


(données)

 le service TELNET (émulation terminal) sur le port 23

 le service SMTP (mail) sur le port 25


 Pour accéder à un service, il faut l'adresse du site et le numéro du
port

 Il faut également que les deux processus communique avec le


même protocole, ce dernier définit :

◦ Le format des messages échangés entre émetteur et récepteur (textuel,


binaire, …)

◦ Les types de messages : requête / réponse /informationnel …

◦ L’ordre d’envoi des messages


 Un socket est un élément logiciel ou une interface logicielle
avec les services du système d’exploitation, grâce à laquelle
un développeur exploitera facilement et de manière uniforme
les services d’un protocole réseau.

 On dit qu’un socket et une API (Application Program Interface)

 Il s’agit d’un modèle permettant la communication inter


processus (IPC - Inter Process Communication) afin de
permettre à divers processus de communiquer aussi bien sur
une même machine qu’à travers un réseau TCP/IP
 C’est un mécanisme d’interface de programmation entre le
programme d'application et les protocoles de communication :

 Permet aux programmes d'échanger des données

 Les applications client/serveur ne voient les couches de


communication qu’à travers l’API socket

 N’implique pas forcément une communication par le réseau, il


existe des socket pour les communications dans le même
ordinateur
 Deux modes de communication par socket existe:

 Le mode connecté (comparable à une communication


téléphonique), utilisant le protocole TCP. Dans ce mode de
communication, une connexion durable est établie entre les deux
processus, de telle façon que l’adresse de destination n’est pas
nécessaire à chaque envoi de données ;

 Le mode non connecté (analogue à une communication par


courrier), utilisant le protocole UDP. Ce mode nécessite l’adresse
de destination à chaque envoi, et aucun accusé de réception n’est
donné.
 Avec les protocoles UDP et TCP, une connexion est
entièrement définie sur chaque machine par :

 le type de protocole (UDP ou TCP)

 l'adresse IP

 le numéro de port associé au processus :


◦ serveur : port local sur lequel les connexions sont attendues
◦ client : allocation dynamique par le système
 java.net comprend la classe ServerSocket, que les serveurs
peuvent utiliser pour écouter et accepter les connexions des
clients

 Pour créer une socket dans un serveur :

 ServerSocket socketserver = new ServerSocket(numer_port,nbr_max,adresse_locale);

 nbr_max est le nombre maximal de connexions traitées


simultanément
 Le client connaît le nom de la machine sur laquelle le serveur
est en exécution et le numéro de port sur lequel il écoute

 le package java.net fournit une classe Socket qui met en


œuvre une connexion bidirectionnelle entre le programme
Java et un autre programme situé sur le réseau

 La création de socket dans le client :

 Socket socket = new Socket(adresse_distante, port_distant, adresse_locale, port_locale)


 Après tentative de connexion, si tout va bien, le serveur
accepte la connexion du client, et reçoit un nouveau socket
qui est directement lié au même port local

 La demande du client est accepté avec :

 Socket socketduserveur = socketserver.accept();

 La méthode accept() est bloquante tant qu'elle n'a pas détecté


de connexion.
 Le serveur sera codé comme suit :

 socketserver = new ServerSocket(2009);


 socketduserveur = socketserver.accept();
 System.out.println("Un client s'est connecté !");
 socketserver.close();
 socketduserveur.close();
 Côté client :

 socket = new Socket(InetAddress.getLocalHost(),2009);


 socket.close();

 Il est très important de toujours refermé la socket après


utilisation !
 Une fois la connexion établit il est nécessaire de récupérer les
flux comme suit :

 getInputStream() de la classe InputStream. Elle nous permet


de gérer les flux entrant ;

 getOutputStream() de la classe OuputStream. Elle nous permet


de gérer les flux sortant.
 Les deux méthodes précédentes nous permettent donc de
gérer les flux en entrée et en sortie

 le type d'entrée et sortie utilisé est:

 BufferedReader et InputStreamReader pour la lecture

 PrintWriter pour l'écriture


 bufferedReader : cette classe permet de lire des caractères à
partir d'un flux tamponné, afin de faire des lectures plus
rapides ;

 InputStreamReader : convertit un flux binaire en flux de


caractères : elle convertit un objet de type InputStream en
objet de type Reader ;

 PrintWriter : la classe PrintWriter ajoute à un flux la possibilité


de faire des écritures sous forme de texte des types primitifs
Java, et des chaînes de caractères.
 socketserver = new ServerSocket(2009);
 System.out.println("Le serveur est à l'écoute du port
"+socketserver.getLocalPort());
 socketduserveur = socketserver.accept();
 System.out.println("Un client s'est connecté");
 out = new PrintWriter(socketduserveur.getOutputStream());
 out.println("Vous êtes connecté !");
 out.flush();
 socketduserveur.close();
 socketserver.close();
 Après établissement de la connexion, le serveur obtient son
socket qu'il utilise pour gérer le flux sortant à l'aide
de socketduserveur.getOutputStream() ;

 ensuite, à l'aide de la méthode println on envoie un message


au client, on utilise flush pour vider le buffer .

 Enfin on ferme la connexion avec close()


 socket = new Socket(InetAddress.getLocalHost(),2009);
 System.out.println("Demande de connexion");

 in = new BufferedReader (new InputStreamReader


(socket.getInputStream()));
 String message_distant = in.readLine();
 System.out.println(message_distant);

 socket.close();
 Après avoir obtenu la socket, on utilise
socket.getInputStream() pour récupérer le flux entrant.

 La méthode readLine() nous permet de lire une chaîne de


caractères. Il existe plusieurs autres méthodes telles :
◦ readInt() permettant de lire un entier ;
◦ readDouble() permettant de lire un nombre de type double ;

 Pour finir, on affiche le message reçu et on ferme notre


socket.
 http://deptinfo.cnam.fr/Enseignement/CycleA/AMSI/cours_systemes/13_synchronisation/synchr.h
tm#Heading10

 « Programmation Système En C sous Linux », Rémy Malgouyres, Université Clermont 1

 « Système d’exploitation, 3eme édition », Andrew tanenbaum.

 « Le modèle client‐serveur », Christian Bulfone

 « ARCHITECTURE CLIENT / SERVEUR », Oumou DIANE,


https://www.supinfo.com/articles/single/2519-architecture-client-serveur

 « ARCHITECTURE CLIENT / SERVEUR », andreu, polytech.univ-montp2

 « Introduction aux sockets », Chabane Refes, Openclassrooms.com

Vous aimerez peut-être aussi