SlideShare une entreprise Scribd logo
1  sur  179
Télécharger pour lire hors ligne
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 1 -
Programmation
système et réseau sous
Windows et Unix
Patrick Ducrot
dp@ensicaen.fr
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 2 -
Plan du document
Description des processus …………………………………………………………………………………………………………………………………… 3
Gestion des processus et communication par tube sous Unix ……………………………………………… 9
Gestion de processus et communication par tube sous Windows ………………………………………… 27
Synchronisation de processus ………………………………………………………………………………………………………………………… 43
Les sémaphores sous Unix …………………………………………………………………………………………………………………………………… 46
Les sémaphores sous Windows …………………………………………………………………………………………………………………………… 50
Les threads ……………………………………………………………………………………………………………………………………………………………………… 55
Les threads sous Unix …………………………………………………………………………………………………………………………………………… 60
Les threads sous Windows …………………………………………………………………………………………………………………………………… 63
Synchronisation de threads ………………………………………………………………………………………………………………………………… 67
Synchronisation de threads sous Unix ……………………………………………………………………………………………………… 70
Synchronisation de threads sous Windows ……………………………………………………………………………………………… 79
Programmation réseau ………………………………………………………………………………………………………………………………………………… 89
Remote Procedure Call ……………………………………………………………………………………………………………………………………………… 129
La bibliothèque SDL …………………………………………………………………………………………………………………………………………………… 157
Programmation réseau IPv6 …………………………………………………………………………………………………………………………………… 161
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 3 -
Description des
processus
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 4 -
Définition d’un processus
z Un processus correspond à l’exécution d’une tâche.
z Aspect dynamique d’un programme.
z Un système d’exploitation doit exécuter « simultanément »
plusieurs processus.
z Chaque processus est composé en mémoire:
• Un espace pour le code
• Un espace pour les données
• Un espace pour la pile d’exécution
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 5 -
Définition des processus
P 1
P 2 P 3
P 4 P 6
P 5
Pile d'exécution
Données
Code
Hiérarchie des processus Structure d’un processus
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 6 -
État d’un processus
z Le passage d’un processus à un autre
est assuré par un ordonnanceur.
Élu Prêt
Bloqué
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 7 -
Descripteurs d’Entrée/Sortie
processus
stdin 0
stdout 1
stderr 2
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 8 -
Création de processus
z Fonctionnement très différent entre
Windows et Unix:
Unix Windows
exec ()
fork ()
CreateProcess ()
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 9 -
Gestion de processus
sous UNIX
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 10 -
Création d’un processus sous
Unix
z Sous Unix, un processus peut se
dupliquer:
pid_t fork(void);
z La fonction renvoie:
• -1 si erreur
• 0 pour le processus fils
• >0 pour le processus père (Process IDentification)
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 11 -
Duplication de processus UNIX
void main ()
{
if (fork () != 0)
{
printf ("Je suis le peren") ;
}
else
{
printf ("je suis le filsn") ;
}
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 12 -
État après le fork ()
if (fork () != 0)
{
printf ("Je suis le peren") ;
}
else
{
printf ("je suis le filsn") ;
} if (fork () != 0)
{
printf ("Je suis le peren") ;
}
else
{
printf ("je suis le filsn") ;
}
Exécution « simultanée »
Père
Fils
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 13 -
Invocation d’un programme
existant
z L'invocation d'un programme existant ne
peut se faire que par le recouvrement du
code du processus appelant grâce à une
des fonctions de la famille exec.
z D’où l’intérêt voire la nécessité de
dupliquer préalablement le processus.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 14 -
La famille de fonctions exec
int execl (char *path,char *arg0,…,char *argn,NULL) ;
int execv (char *path,char *argv []) ;
int execle (char *path, char *arg0,…,char *argn,NULL,char *envp[]) ;
int execve (char *path,char *argv [], char *envp []) ;
int execlp (char *file,char *arg0,…,char argn,NULL) ;
int execvp (char *file,char *argv []) ;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 15 -
Exemple exec
#include <stdio.h>
void main ()
{
if ( fork () != 0)
{
printf ("je suis le pere, je continue icin") ;
}
else
{
printf ("fils: je me transformen") ;
execl ("/bin/date","date",NULL) ;
}
}
père
/bin/date
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 16 -
Fin d’un processus
z Un processus s’arrête lorsque:
• Il n’a plus d’instruction à exécuter
• Il exécute un appel à la fonction
void exit (int status) ;
z Lorsqu’un processus fils est terminé, celui-ci sera retiré
de la table des processus si:
• Le père acquitte la fin du processus fils par un appel à
la fonction: int wait(int *code_de_sortie) ;
• Le père ignore la fin des processus fils par un appel à
la fonction:
signal (SIGCHLD,SIG_IGN) ;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 17 -
Gestion de signaux
z Un signal permet de dérouter l'exécution d'un processus.
z A réception d'un signal un processus peut:
• se terminer (comportement par défaut)
• l'ignorer
• exécuter une fonction particulière
z Un signal peut être envoyé par:
• une commande shell:
kill –num_signal PID
• par programmation
int kill (int pid, int signal) ;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 18 -
Quelques signaux Unix
signal émis par un fils qui se termine
à son père
20
SIGCLD
signal d’interruption radicale
9
SIGKILL
^
3
SIGQUIT
^C
2
SIGINT
signal émis lors d’une déconnexion
1
SIGUP
Commentaires
No
signal
Nom du
signal
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 19 -
Détournement d'un signal
z Un processus peut détourner les signaux reçus et modifier son comportement
par l’appel de la fonction :
void (*signal(int signal, void (*fonction)(int)))
le deuxième argument pouvant prendre les valeurs:
Le processus exécutera fonction, définie par
l’utilisateur, à l’arrivée de l’interruption n. Il reprendra
ensuite au point où il a été interrompu
void fonction(int n)
le processus rétablira son comportement par défaut lors
de l’arrivée de l’interruption (la terminaison)
SIG_DFL
le processus ignorera l’interruption correspondante
SIG_IGN
Action
Nom
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 20 -
Exemple détournement signal
#include <stdio.h>
#include <sys/signal.h>
void detourne (int num_signal)
{
printf ("signal num %dn",num_signal) ;
}
void main ()
{
signal (SIGINT,detourne) ;
while (1) sleep (10) ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 21 -
Communication par tube
anonyme
z 2 processus disposant d'un lien de
parenté peuvent échanger de
l'information par l'intermédiaire d'un tube
anonyme.
père
fils
Échange
d'information
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 22 -
Les tubes anonymes
z Le support de communication est le système de fichier
z La communication est en mode caractère.
z Création d'un tube anonyme:
int p [2] ;
pipe (p) ;
p [0] descripteur en lecture
p[1] descripteur en écriture
p [1]
p [0]
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 23 -
Les tubes anonymes
- Lecture/Ecriture dans un tube anonyme :
int read (int desc, char *buf, int nb)
int write (int desc, char *buf, int nb)
- Fermeture d'un descripteur
void close (int desc)
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 24 -
Les tubes nommés
z Les tubes nommés portent un nom ;)
z Ils permettent à deux processus sans lien de
parenté de s’échanger de l’information.
Processus A Processus B
Tube nommé
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 25 -
Tubes nommés
z Création d'un tube nommé avec une commande shell
mkfifo tube
z Ouverture/Lecture/Ecriture/Fermeture
int open (char *file,int mode,int droits)
int read (int desc,char *buf,int nb)
int write (int desc,char *buf,int nb)
void close (desc)
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 26 -
Duplication de descripteurs
- Un descripteur de fichier peut être dupliqué vers une entrée
disponible
- Duplication d’un descripteur sur le plus petit descripteur
disponible
int dup (int desc)
- Duplication d’un descripteur vers un descripteur spécifié (avec
éventuellement fermeture de celui-ci)
int dup2 (int desc1, int desc2)
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 27 -
Gestion de processus
sous Windows
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 28 -
Création de processus sous
Windows
z Lorsqu'un processus sous Windows est créé, son premier thread
(thread primaire) est créé automatiquement par le système.
z Le thread primaire peut créer d'autres threads qui peuvent à leur
tour en créer d'autres.
z Un thread quelconque peut créer un processus par un appel à la
fonction CreateProcess ()
z Rôle de CreateProcess () :
• Crée un espace d'adressage virtuel pour ce processus
• Charge le processus dans cet espace
• Définit le thread primaire pour ce processus
• Lance l’exécution du thread primaire
z CreateProcess renvoie TRUE si la création est un succès
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 29 -
La fonction CreateProcess ()
BOOL CreateProcess (
LPCTSTR lpApplicationName,
LPCTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 30 -
Paramètres de CreateProcess ()
1/5
z lpApplicationName : identifie le nom du fichier exécutable qui
peut se trouver :
- Dans le répertoire courant, dans le répertoire SYSTEM et
dans les répertoires spécifiés dans la commande PATH
- On peut passer NULL : dans ce cas, on considère que le nom
du fichier exécutable est le 1ier élément (jusqu'au premier
espace) du paramètre lpCommandLine
z lpCommandLine : spécifie les arguments de la ligne de
commande à passer au processus incluant le nom de
l'exécutable si lpApplicationName vaut NULL.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 31 -
Paramètres de CreateProcess ()
2/5
z lpProcessAttributes et lpThreadAttributes : : pointent sur une
structure SECURITY_ATTRIBUTES qui indique qui a le droit
de se partager l'objet et si d'autres processus ont le droit de le
modifier; On peut passer NULL, dans ce cas, le processus et le
thread reçoivent le descripteur par défaut et personne ne
pourra en hériter
z bInheritHandles : indique si l'identificateur de l'objet
processus/thread est héritant. En général un objet possède des
Id's différents lorsqu'il est utilisé dans des processus différents.
Toutefois, Windows permet aux Id's d'être hérités
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 32 -
Paramètres de CreateProcess ()
3/5
z dwCreationFlags : identifie des indicateurs (séparés par des
OU logiques) qui affectent la création
Exemples : CREATE_SUSPENDED
CREATE_NEW_CONSOLE
…
z lpEnvironment : pointe sur un bloc de mémoire contenant les
chaînes d'environnement utilisées par le processus. Le plus
souvent on passe NULL, ce qui signifie que le processus enfant
emploie les mêmes chaînes d'environnement que son père
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 33 -
Paramètres de CreateProcess ()
4/5
z lpCurrentDirectory : permet au processus appelant
CreateProcess d'indiquer à Windows le nom du répertoire
courant pour le nouveau processus. Si on passe NULL, le
répertoire courant est le même que celui de l'application
l'ayant créée
z lpStartupInfo : pointe sur une structure STARTUPINFO
qui contient des membres que l'on peut affecter, soit pour
des applications console ou pour des applications
graphiques ou les deux, pour le lancement
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 34 -
Paramètres de CreateProcess ()
5/5
z lpProcessInformation : pointe sur une structure
PROCESS_INFORMATION que CreateProcess remplira avant
de retourner ; la structure a l'aspect suivant :
typedef struct _PROCESS_INFORMATION
{
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
} PROCESS_INFORMATION;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 35 -
Exemple de CreateProcess
#include <windows.h>
void main ()
{
STARTUPINFO si ;
PROCESS_INFORMATION pi ;
GetStartupInfo (&si) ; // Initialisation de la STARTUPINFO
CreateProcess (NULL,
"notepad",
NULL,NULL,
FALSE,
0,NULL,NULL,
&si,&pi) ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 36 -
La structure STARTUPINFO
typedef struct STARTUPINFO
{
DWORD cb; // taille de la structure
LPTSTR lpReserved; // doit être laissé à NULL
LPTSTR lpDesktop; // nom de l'objet bureau
LPSTR lpTitle; // légende pour le titre de la fenêtre (mode console)
DWORD dwX; // coin supérieur gauche de la fenêtre
DWORD dwY;
DWORD dwXSize; // largeur nouvelle fenêtre
DWORD dwYSize; // hauteur nouvelle fenêtre
DWORD dwXCountChars; // largeur nouvelle fenêtre console
DWORD dwYCountChars; // hauteur nouvelle fenêtre console
DWORD dwFillAttribute; // couleur texte et fond pour la console
DWORD dwFlags; // activation des champs de la structure
WORD wShowWindow; // valeur de iCmdShow
WORD cbReserved2; // zéro
LPBYTE lpReserved2; // NULL
HANDLE hStdInput; // handle d'entrée standard
HANDLE hStdOutput; // handle de sortie standard
HANDLE hStdError; // handle d'erreur standard
} STARTUPINFO, *LPSTARTUPINFO ;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 37 -
Création/Fermeture d'un tube
anonyme sous Windows
BOOL CreatePipe ( PHANDLE hRead, // Handle de lecture
PHANDLE hWrite, // Handle d'écriture
LPSECURITY_ATTRIBUTES lpPipeAttributes, // Privilège d'accès
DWORD nSize) // taille du tube, valeur par défaut si 0
typedef struct _SECURITY_ATTRIBUTES
{
DWORD nLength; // Doit contenir la taille de la structure
LPVOID lpSecurityDescriptor; // Paramètre de sécurité
BOOL bInheritHandle; // TRUE si le pipe doit être transmis par héritage
} SECURITY_ATTRIBUTES;
BOOL CloseHandle( HANDLE hObject ) ; // Handle à fermer
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 38 -
Utilisation d'un tube anonyme
sous Windows
BOOL ReadFile (
HANDLE hFile, // handle de lecture
LPVOID lpBuffer, // adresse de réception des données
DWORD nNumberOfBytesToRead, // Nombre d'octets réservés
LPDWORD lpNumberOfBytesRead, // adresse de réception du nombre d'octets lus
LPOVERLAPPED lpOverlapped // lecture asynchrone
);
BOOL WriteFile (
HANDLE hFile, // handle d'écriture
LPVOID lpBuffer, // Adresse des données à écrire
DWORD nNumberOfBytesToWrite, // nombre d'octets à écrire
LPDWORD lpNumberOfBytesWritten, // adresse de réception du nombre d'octets à écrire
LPOVERLAPPED lpOverlapped // Ecriture asynchrone
);
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 39 -
Tubes nommés sous Windows
z Concept très évolué sous Windows:
• Un serveur (créateur du tube nommé) peut avoir plusieurs
clients (instance)
• Les clients et le serveur peuvent être sur des machines
distinctes (moyennant les problèmes de droits d'accès).
Serveur
Clients
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 40 -
Création d'un tube nommé sous
Windows
HANDLE CreateNamedPipe(
LPCTSTR lpName, // Nom du tube: .pipenom
DWORD dwOpenMode, // Mode d'ouverture du fichier
DWORD dwPipeMode, // Mode d'ouverture spécifique au tube
DWORD nMaxInstances, // Nombre maximal d'instances
DWORD nOutBufferSize, // Taille du buffer de sortie
DWORD nInBufferSize, // Taille du buffer d'entrée
DWORD nDefaultTimeOut, // Timeout si un client appelle
WaitNamedPipe
LPSECURITY_ATTRIBUTES lpSecurityAttributes // Privilège d'accès
);
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 41 -
Exemple tube nommé sous
Windows
tube = CreateNamedPipe (".pipeServeurDessin",
PIPE_ACCESS_DUPLEX | FILE_FLAG_WRITE_THROUGH,
PIPE_TYPE_MESSAGE | PIPE_WAIT,
1,0,0,0,NULL) ;
if (tube == INVALID_HANDLE_VALUE)
{
LPVOID lpMsgBuf;FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf, 0, NULL );// Display the string.
::MessageBox( NULL, (char *)lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );
LocalFree( lpMsgBuf );
MessageBox ("Le tube de communication n'a pas pu être créé","Erreur",MB_ICONERROR |
MB_OK) ;
PostQuitMessage (0) ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 42 -
Connexion à un tube nommé
sous Windows
HANDLE CreateFile (
LPCTSTR lpFileName, // Nom du tube
DWORD dwDesiredAccess, // Mode d'accès (lecture/écriture)
// GENERIC_READ si le tube a été créé avec PIPE_ACCESS_OUTBOUND
//GENERIC_WRITE si le tube a été créé avec PIPE_ACCESS_INBOND
// GENERIC_WRITE | GENERIC_READ si duplex
DWORD dwShareMode, // 0 pour interdire le partage du tube avec d'autres processus
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // Privilège d'accès
DWORD dwCreationDistribution, // OPEN_EXISTING puisqu'on ouvre un tube existant
DWORD dwFlagsAndAttributes, //FILE_FLAG_WRITE_THROUGH pour une écriture synchrone
HANDLE hTemplateFile // Pas de signification pour les tubes
);
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 43 -
Synchronisation de
processus
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 44 -
Synchronisation de processus
z Plusieurs processus peuvent entrer en
conflit pour l'accès à une ressource:
• Accès en écriture à un fichier texte.
• Accès à de la mémoire partagée.
• …
z On peut souhaiter limiter le nombre
d'accès simultanés à une ressource:
• Accès en lecture à un fichier texte.
• …
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 45 -
Définition d'un sémaphore
z Les sémaphores est un concept introduit par Djikstra.
z Un sémaphore est une valeur entière, initialisée avec le
nombre d'accès simultanés autorisés, associée à 2
fonctions atomiques (P (sem) et V (sem) ) pour acquérir
et rendre un accès et une file d'attente.
z Acquérir un accès revient à décrémenter la valeur du
sémaphore; si la valeur devient <0, le processus est
placé en file d'attente.
z Rendre un accès revient à incrémenter la valeur du
sémaphore et réveiller un processus si la valeur est <= 0.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 46 -
Les Sémaphores
sous Unix
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 47 -
Les sémaphores sous Unix
z Unix gère les sémaphores à la norme "Posix" (proche de la
définition des sémaphores de Djikstra) qui seront vus au
chapitre des threads et des sémaphores "Unix" qui sont des
tableaux de sémaphores.
z Les types et prototypes nécessaires pour manipuler les
sémaphores "Unix" sont:
#include <sys/ipc.h>
#include <sys/sem.h>
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 48 -
Manipulations de sémaphores
sous Unix (1/2)
z Création:
int semget(key_t clé, int NombreSéma, int flag);
Exemple:
cle = ftok("nom_fichier_existant", 'A');
idSema = semget(cle, 5, IPC_CREAT | 0600); // Création d'un tableau de 5 sémaphores
// avec des droits d'accès exclusifs.
z Manipulation (initialisation, consultation, destruction):
int semctl(int idSema, int NombreSéma, int commande, ushort semarray);
Exemple:
semctl (semid,0,SETVAL,1) ; // initialisation à 1 du sémaphore numéro 0
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 49 -
Manipulations de sémaphores
sous Unix (2/2)
z Acquisition/Libération:
int semop(int idSema, struct sembuf *sops, size_t NbOpérat) ;
Exemple:
struct sembuf op ;
op.sem_num = 0 ; // Indice du sémaphore au sein du tableau de sémaphore
op.sem_op = 1 ; // 1 pour acquisition, -1 pour libération
op.sem_flg = 0 ; // 0 pour acquisition bloquante
semop (semid,&op,1) ; // Acquisition, si la valeur est < 0, la fonction sera bloquante
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 50 -
Les sémaphores sous
Windows
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 51 -
Création sémaphore Windows
z Création d'un sémaphore:
HANDLE CreateSemaphore (
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
LONG lInitialCount,
LONG lMaximumCount,
LPCTSTR lpName );
z Ouverture d'un sémaphore existant:
HANDLE OpenSemaphore
( DWORD dwDesiredAccess, // SEMAPHORE_ALL_ACCESS
// SEMAPHORE_MODIFY_STATE
BOOL bInheritHandle,
LPCTSTR lpName );
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 52 -
Utilisation sémaphore Windows
z Demande d'un accès:
DWORD WaitForSingleObject( HANDLE hHandle, // Handle du sémaphore
DWORD dwMilliseconds // time-out en millisecondes );
z Restitution d'accès:
BOOL ReleaseSemaphore ( HANDLE hSemaphore, // handle du sémaphore
LONG lReleaseCount, // Valeur à ajouter au sémaphore
LPLONG lpPreviousCount // Récupération de la valeur
// précédente
) ;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 53 -
Exemple (1/2)
#include <windows.h>
#include <stdio.h>
void main ()
{
HANDLE sem ;
LONG previous ;
int i ;
sem= CreateSemaphore (NULL,1,1,"semaphore") ;
if (sem == NULL) { exit (1) ; }
for (i = 0 ; i != 10 ; i++)
{
WaitForSingleObject (sem,INFINITE) ;
printf ("A: j'ai prisn") ;
Sleep (5000) ;
printf ("A: je liberen") ;
ReleaseSemaphore (sem,1,&previous) ;
}
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 54 -
Exemple (2/2)
#include <windows.h>
#include <stdio.h>
void main ()
{
HANDLE sem ;
LONG previous ;
int i ;
sem = OpenSemaphore (SEMAPHORE_ALL_ACCESS,FALSE,"semaphore") ;
if (sem == NULL) { exit (1) ; }
for (i = 0 ; i != 10 ; i++)
{
WaitForSingleObject (sem,INFINITE) ;
printf ("B: j'ai prisn") ;
Sleep (3000) ;
printf ("B: je liberen") ;
ReleaseSemaphore (sem,1,&previous) ;
}
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 55 -
Les threads
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 56 -
Définition d'un Thread
z Un thread est une unité d'exécution au sein d'un
processus.
z Un processus peut être composé de plusieurs
threads.
z Des quantums de temps seront alloués à chacun
des threads, en fonction de leur priorité.
z Tous les threads d'un même processus partagent le
même espace mémoire.
z L'échange d'informations entre deux threads est plus
rapide qu'entre deux processus mais peut engendrer
des conflits d'accès aux ressources.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 57 -
Définition d'un thread
th1
th2
th3
Processus 1 Processus 2
th1
th2
thread
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 58 -
Similitudes threads
Unix/Windows
z Chaque thread dispose d'un point d'entrée (fonction).
z La fonction thread dispose d'un et d'un seul argument
totalement à la charge du programmeur.
z La fonction thread retourne une valeur.
z La fonction thread doit utiliser les paramètres et variables
locaux aussi souvent que possible pour éviter les conflits avec
la zone globale.
z La mort du thread principal entraîne la mort de tous les threads.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 59 -
Création de threads
Unix Windows
pthread_create ( )
pthread_exit ( )
pthread_join ( )
CreateThread ( )
ExitThread ( )
WaitForSingleObject ( )
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 60 -
Threads Unix
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 61 -
Unix: création d'un thread
#include <pthread.h>
int pthread_create (
pthread_t * thread, /* HANDLE */
pthread_attr_t *attr,
void * (*start_routine)(void *),
void * arg
);
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 62 -
Exemple Thread Unix
int main ()
{
pthread_t a_thread ;
void *thread_result ;
if ( pthread_create (&a_thread,NULL,thread_function,
(void *) message) < 0)
{
perror ("erreur creation du thread") ;
exit (EXIT_FAILURE) ;
}
printf ("On attend la fin du threadn") ;
if ( pthread_join (a_thread,&thread_result) < 0)
{
perror ("erreur join") ;
exit (EXIT_FAILURE) ;
}
printf ("Fin du join, le thread a retourne %sn", (char *)
thread_result) ;
printf ("message contient maintenant : %sn",message) ;
exit (EXIT_SUCCESS) ;
}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
char message[] = "Bonjour" ;
void *thread_function (void *arg)
{
printf ("thread demarre avec %sn", (char *) arg) ;
sleep (3) ;
strcpy (message,"Bye") ;
pthread_exit ("au revoir") ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 63 -
Threads Windows
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 64 -
Création thread Windows
HANDLE CreateThread
(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 65 -
Exemple thread Windows (1/2)
#include <windows.h>
#include <stdio.h>
char message [ ] = "Bonjour" ;
DWORD WINAPI thread_function (PVOID arg)
{
printf ("thread demarre avec %sn", (char *) arg) ;
Sleep (3000) ;
strcpy (message,"Bye") ;
return 100 ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 66 -
Exemple thread Windows (2/2)
void main ()
{
HANDLE a_thread ;
DWORD a_threadId ;
DWORD thread_result ;
if ( (a_thread = CreateThread (NULL,0,thread_function,(PVOID)message,0,&a_threadId) ) == NULL)
{
perror ("erreur creation du thread") ;
exit (EXIT_FAILURE) ;
}
printf ("On attend la fin du threadn") ;
if ( WaitForSingleObject (a_thread,INFINITE) != WAIT_OBJECT_0)
{
perror ("erreur join") ;
exit (EXIT_FAILURE) ;
}
GetExitCodeThread (a_thread,&thread_result) ;
printf ("Fin du join, le thread a retourne %dn",thread_result) ;
printf ("message contient maintenant : %sn",message) ;
exit (EXIT_SUCCESS) ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 67 -
Synchronisation
des threads
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 68 -
Synchronisation threads
z Tous les threads s'exécutent dans le même espace
mémoire.
z Deux threads peuvent vouloir accéder à la même
zone mémoire "en même temps".
z Sans précaution, le résultat sera imprévisible.
z L'accès à des zones mémoires partagées doit donc
être réglementé.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 69 -
Un outil de synchronisation: le
mutex
z Un mutex est un sémaphore binaire pouvant prendre un
état verrouillé ou déverrouillé.
z Un mutex ne peut être partagé que par des threads d'un
même processus.
z Un mutex ne peut être verrouillé que par un seul thread à
la fois.
z Un thread qui tente de verrouiller un mutex déjà verrouillé
est suspendu jusqu'à ce que le mutex soit déverrouillé.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 70 -
Synchronisation
Threads Unix
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 71 -
Exemple programme erroné
int main ()
{
int res1,res2 ;
pthread_t a_thread1,a_thread2 ;
void *thread_result1,*thread_result2 ;
res1 = pthread_create (&a_thread1,NULL,function,NULL) ;
res2 = pthread_create (&a_thread2,NULL,function,NULL) ;
printf ("On attend la fin des threadsn") ;
pthread_join (a_thread1,&thread_result1) ;
pthread_join (a_thread2,&thread_result2) ;
printf ("compteur = %dn",compteur) ;
}
#include <stdio.h>
#include <pthread.h>
int compteur = 0 ;
void *function (void
*arg)
{
int i,a ;
for (i = 0 ; i < 10 ; i++)
{
a = compteur ; a = a
+ 1 ;
sleep (1) ;
compteur = a ;
}
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 72 -
Synchronisation des threads
Unix
z La synchronisation des threads peut se
faire avec:
• un sémaphore « Unix » (vu avec les processus).
• Un sémaphore « Posix ».
• un mutex.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 73 -
Les sémaphores "Posix"
z Unix gère les sémaphores à la norme "Posix"
(proche de la définition des sémaphores de Djikstra).
Sous Linux, ils ne sont utilisables que pour les
threads (2ème argument de sem_init doit être 0).
z Les types et prototypes nécessaires pour manipuler
les sémaphores "Posix" sont dans le fichier d'entête
"semaphore.h".
z Un sémaphore est une variable de type sem_t.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 74 -
Manipulation d'un sémaphore
Posix
z Initialisation:
int sem_init(sem_t *sem, int pshared, unsigned int value);
z Acquisition d'un accès:
• bloquant: int sem_wait(sem_t * sem);
• non bloquant: int sem_trywait(sem_t * sem);
z Libération d'un accès:
int sem_post(sem_t * sem);
z Consultation de la valeur d'un sémaphore:
int sem_getvalue(sem_t * sem, int * sval);
z Destruction d'un sémaphore:
int sem_destroy(sem_t * sem);
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 75 -
Exemple sémaphore Posix
int main ()
{
int res1,res2 ;
pthread_t a_thread1,a_thread2 ;
void *thread_result1,*thread_result2 ;
sem_init (&sem,0,1) ;
res1 = pthread_create (&a_thread1,NULL,function,NULL) ;
res2 = pthread_create (&a_thread2,NULL,function,NULL) ;
printf ("On attend la fin des threadsn") ;
pthread_join (a_thread1,&thread_result1) ;
pthread_join (a_thread2,&thread_result2) ;
sem_destroy (&sem) ;
printf ("compteur = %dn",compteur) ;
}
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
int compteur = 0 ;
sem_t sem ;
void *function (void *arg)
{
int i,a ;
for (i = 0 ; i < 10 ; i++)
{
sem_wait (&sem) ;
a = compteur ;
a = a + 1 ;
sleep (1) ;
compteur = a ;
sem_post (&sem) ;
}
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 76 -
Mutex sous Unix
z Un mutex est une variable de type pthread_mutex_t
z Elle peut être initialisée:
• par la constante PTHREAD_MUTEX_INITIALIZER
• Par un appel à la fonction:
int pthread_mutex_init ( pthread_mutex_t *mutex,
const pthread_mutexattr_t *mutexattr ) ;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 77 -
Utilisation mutex Unix
z Verrouillage d'un mutex
int pthread_mutex_lock (pthread_mutex_t *mutex);
z Déverrouillage d'un mutex
int pthread_mutex_unlock (pthread_mutex_t *mutex) ;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 78 -
Exemple mutex Unix
pthread_mutex_t monMutex = PTHREAD_MUTEX_INITIALIZER ;
void *function (void *arg)
{
int i,a ;
for (i = 0 ; i < 10 ; i++)
{
pthread_mutex_lock (&monMutex) ;
a = compteur ;
a = a + 1 ;
sleep (1) ;
compteur = a ;
pthread_mutex_unlock (&monMutex) ;
}
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 79 -
Synchronisation
Threads Windows
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 80 -
Synchronisation des threads
Windows
z La synchronisation des threads peut se faire avec:
• un sémaphore (déjà vu avec les processus).
• un mutex.
• une section critique.
• un verrou sur les variables.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 81 -
Mutex Windows
z Création d’un mutex:
HANDLE CreateMutex (
LPSECURITY_ATTRIBUTES lpMutexAttributes,
BOOL bInitialOwner, // Si TRUE, le mutex est créé et pris
LPCTSTR lpName // Nom du mutex
);
z Ouverture d’un mutex existant:
HANDLE OpenMutex (
DWORD dwDesiredAccess, // MUTEX_ALL_ACCESS ou SYNCHRONIZE
BOOL bInheritHandle, // Flag d’héritage
LPCTSTR lpName // Nom du mutex
);
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 82 -
Mutex Windows
z Acquisition d’un mutex:
DWORD WaitForSingleObject (
HANDLE hHandle,
DWORD dwMilliseconds
);
z Libération d’un mutex:
BOOL ReleaseMutex (HANDLE hMutex);
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 83 -
Exemple Mutex 1/2
#include <stdio.h>
#include <windows.h>
int compteur = 0 ;
DWORD WINAPI thread (LPVOID arg)
{
int i,a ;
for (i = 0 ; i != 10 ; i++)
{
WaitForSingleObject ( (HANDLE) arg,INFINITE) ;
a= compteur ;
Sleep (1000) ;
a = a + 1 ; compteur = a ;
ReleaseMutex ( (HANDLE) arg) ;
}
return 0 ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 84 -
Exemple mutex 2/2
void main ()
{
DWORD ThreadId ;
HANDLE ta,tb ;
HANDLE mutex ;
mutex = CreateMutex (NULL,FALSE,"MonMutex") ;
ta = CreateThread (NULL,0,thread,mutex,0,&ThreadId) ;
tb = CreateThread (NULL,0,thread,mutex,0,&ThreadId) ;
WaitForSingleObject (ta,INFINITE) ;
WaitForSingleObject (tb,INFINITE) ;
printf ("compteur = %dn",compteur) ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 85 -
Section critique
z VOID InitializeCriticalSection (
LPCRITICAL_SECTION lpCriticalSection // Adresse de la section critique
);
z VOID EnterCriticalSection (
LPCRITICAL_SECTION lpCriticalSection // Adresse de la section critique
);
z VOID LeaveCriticalSection (
LPCRITICAL_SECTION lpCriticalSection // Adresse de la section critique
);
z VOID DeleteCriticalSection (
LPCRITICAL_SECTION lpCriticalSection // Adresse de la section critique
);
z BOOL TryEnterCriticalSection (
LPCRITICAL_SECTION lpCriticalSection // Adresse de la section critique
);
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 86 -
Exemple de section critique
#include <stdio.h>
#include <windows.h>
CRITICAL_SECTION verrou ;
DWORD WINAPI function_thread (LPVOID param)
{
int i ;
char *name = (char *) param ;
EnterCriticalSection (&verrou) ;
for (i = 0 ; i != 1000 ; i++)
{
printf ("%s: %dn",name,i) ;
}
LeaveCriticalSection (&verrou) ;
return 0 ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 87 -
Exemple de section critique
(2/2)
void main (int argc,char **argv [])
{
HANDLE ta,tb ;
DWORD ThreadId ;
InitializeCriticalSection (&verrou) ;
ta = CreateThread (NULL,0,function_thread,"Thread A",0,&ThreadId) ;
tb = CreateThread (NULL,0,function_thread,"Thread B",0,&ThreadId) ;
Sleep (10000) ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 88 -
Les fonctions "Interlocked"
z LONG InterlockedIncrement( LPLONG lpAddend) ; // Pointeur sur la variable à incrémenter
z LONG InterlockedDecrement( LPLONG lpAddend) ; // Pointeur sur la variable à décrémenter
z PVOID InterlockedCompareExchange(
PVOID *Destination, // pointer to the destination pointer
PVOID Exchange, // the exchange value
PVOID Comperand // the value to compare
);
z LONG InterlockedExchange( LPLONG Target, // pointer to the 32-bit value to exchange
LONG Value // new value for the LONG value pointed to by Target
);
z LONG InterlockedExchangeAdd (
PLONG Addend, // pointer to the addend
LONG Increment // increment value
);
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 89 -
Programmation
réseau
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 90 -
Modèle OSI
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 91 -
Communication dans le modèle
OSI
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 92 -
L'implémentation IP
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 93 -
Architecture client/serveur
z On construit, au-dessus des protocoles de transmission, des applications
reposant sur un ou plusieurs serveurs et des clients.
z Un serveur propose un ou plusieurs services (par exemple l'heure, le transfert
de fichiers, etc.).
z Un client utilise les services proposés.
z Un client émet une requête dans un protocole donné (TCP/IP, UDP/IP) en
précisant l'adresse de la machine et le service souhaité: le port de
communication.
z Le serveur est à l'écoute de ce port, détecte la requête et fournit la réponse à
l'adresse et sur le port du client.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 94 -
Architecture client/serveur
serveur
port 2143
client
client
requête
réponse requête
réponse
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 95 -
Allocation des ports
z Un port est un entier sur 16 bits.
z Les ports < 1024 sont privilégiés.
z Certains ports sont alloués à des services reconnus; une liste
peut être trouvée dans:
• /etc/services sous Unix
• C:WINNTsystem32driversetcservices sous Windows XP
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 96 -
Extrait du fichier "services"
echo 7/tcp
echo 7/udp
discard 9/tcp sink null
discard 9/udp sink null
systat 11/tcp users #Utilisateurs actifs
systat 11/tcp users #Utilisateurs actifs
daytime 13/tcp
daytime 13/udp
chargen 19/tcp ttytst source #Generateur de caracteres
chargen 19/udp ttytst source #Generateur de caracteres
ftp-data 20/tcp #FTP donnees
ftp 21/tcp #FTP controle
ssh 22/tcp #SSH Remote Login
telnet 23/tcp
smtp 25/tcp mail #Format SMTP
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 97 -
Les sockets
z Interface de programmation proposée par l'Unix de Berkeley et
implémenté par WinSock de Trumpet pour Windows 3.x
z Une socket peut être vue comme un point de communication
entre processus.
z Une socket peut être vue comme un triplé
(protocole,adresse,port).
z Les sockets permettent des échanges bidirectionnels entre
processus.
z Une socket est considérée comme un descripteur de fichiers
par le système d'exploitation.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 98 -
Processus/Socket
processus
socket
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 99 -
Les fonctions de programmation
réseau
z Fonctions sensiblement identiques sous Unix et Windows.
z Sous Windows, l'utilisation d'une socket doit être précédée par
un appel à la fonction:
int WSAStartup ( WORD wVersionRequested,
LPWSADATA lpWSAData );
Cela permet d'indiquer quelle version des sockets Windows
(winsock) est nécessaire.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 100 -
Exemple d'appel de WSAStartup
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Probleme avec la DLL winsock */
return;
}
// Utilisation des sockets
// …
WSACleanup () ; // libération des zones mémoires allouées
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 101 -
La compatibilité winsock
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 102 -
Création d'une socket
z Unix:
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
Retourne –1 en cas d'échec
z Windows:
#include <windows.h>
SOCKET socket ( int af, int type, int protocol );
Retourne INVALID_SOCKET en cas d'échec
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 103 -
Arguments de la fonction socket
IPPROTO_TCP, IPPROTO_UDP, IPPROTO_RAW
En général, il y a un protocole par type et il n'est pas utile de le
spécifier. S'il y en a plusieurs, on peut l'indiquer.
protocol
SOCK_STREAM Garantie l'intégrité de la transmission.
SOCK_DGRAM Transmission sans connexion, sans garantie de
datagrammes de longueur fixe.
SOCK_RAW Transmissions internes aux système (nécessite un
accès privilégié).
…
type
PF_UNIX protocole local
PF_INET protocole Internet
PF_INET6 protocole Internet IPv6
…
domain
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 104 -
Exemples de création de socket
z Socket internet sans connexion (UDP/IP)
socket (PF_INET,SOCK_DGRAM,IPPROTO_UDP)
z Socket internet avec connexion (TCP/IP)
socket (PF_INET,SOCK_STREAM,IPPROTO_TCP)
z Socket de bas niveau:
socket(PF_INET, SOCK_RAW, IPPROTO_RAW)
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 105 -
Communication en mode
Internet non connecté
Serveur Client
Création socket UDP
Documentation structure
adresse (port d'écoute)
Attachement socket/adresse
Lecture / Écriture
Création socket UDP
Documentation structure
adresse (IP,port)
Écriture/Lecture
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 106 -
Structure d'adresse
z On manipule des structures d'adresses dont le type générique
est: struct sockaddr
z Toutes les fonctions manipulant des adresses sont prototypées
avec ce type.
z En fonction du domaine, on utilisera des structures d'adresses
particulières:
z Dans le domaine Unix (PF_UNIX), on manipule des adresses
de type struct sockaddr_un
z Dans le domaine Internet (PF_INET), on manipule des
adresses de type struct sockaddr_in
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 107 -
La structure struct sockaddr_in
#include <netinet/in.h>
struct sockaddr_in
{
short sin_family; /* AF_INET */
unsigned short sin_port; /* Port d'écoute ou de connexion */
struct in_addr sin_addr; /* INADDR_ANY ou IP de connexion */
char sin_zero[8]; /* Pas utilisé */
};
struct in_addr { u_long s_addr; };
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 108 -
Remplissage du champ sin_port
z Attention à la représentation des entiers: utiliser la fonction
htons ()
Exemple:
struct sockaddr_in addr ;
addr.sin_port = htons (2000) ;
z Les fonctions de conversion
unsigned long int htonl(unsigned long int hostlong);
unsigned short int htons(unsigned short int hostshort);
unsigned long int ntohl(unsigned long int netlong);
unsigned short int ntohs(unsigned short int netshort);
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 109 -
Remplissage du champ
sin_addr.addr
z Méthode 1
addr.sin_addr.addr = inet_addr ("193.49.200.147") ;
z Méthode 2
struct hostent {
char *h_name; /* Nom officiel de la machine */
char **h_aliases; /* liste d'alias */
int h_addrtype; /* type d'adresse */
int h_length; /* longueur de l'addresse */
char **h_addr_list; /* liste d'adresses */
}
struct hostent *host ;
host = gethostbyname ("www.ensicaen.fr") ;
memcpy ( &addr.sin_addr.s_addr,host->h_addr_list [0],host->length) ;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 110 -
Attachement socket/adresse
z Unix :
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
Retourne –1 en cas d'erreur, 0 sinon
z Windows:
int bind ( SOCKET s, const struct sockaddr FAR* name, int namelen );
Retourne SOCKET_ERROR en cas d'erreur, 0 sinon
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 111 -
Lecture d'une socket en mode
non connecté
z Unix :
int recvfrom ( int s, void *buf, int len, unsigned int flags,
struct sockaddr *from, int *fromlen);
Retourne: Nombre d'octets lus ou –1 sinon
z Windows:
int recvfrom ( SOCKET s, char FAR* buf, int len, int flags,
struct sockaddr FAR* from, int FAR* fromlen )
Retourne: Nombre d'octets lus ou 0 si la socket a été fermée ou SOCKET_ERROR
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 112 -
Écriture sur une socket en mode
non connecté
z Unix :
int sendto ( int s, const void *msg, int len, unsigned int flags,
const struct sockaddr *to, int tolen);
Retourne le nombre de caractères écrits, -1 sinon
z Windows:
int sendto ( SOCKET s, const char FAR * buf, int len, int flags,
const struct sockaddr FAR * to, int tolen );
Retourne le nombre de caractères écrits, SOCKET_ERROR sinon
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 113 -
Fermeture d'une socket
z Unix :
int close(int fd);
Retourne 0 ou –1 en cas d'échec
z Windows:
int closesocket ( SOCKET s );
Retourne 0 ou SOCKET_ERROR en cas d'échec
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 114 -
Communication en mode
Internet connecté
Serveur Client
Création socket d'écoute TCP
Documentation structure
adresse (port d'écoute)
Documentation structure
adresse (IP,port)
Attachement socket/adresse
Attente client Æ obtient une socket
de service
Création socket TCP
Création d'un processus/thread
Lecture/Écriture
père:
fermeture
éventuelle
socket de
service
fils:
fermeture
éventuelle
socket
d'écoute
Connexion au serveur
Lecture/Écriture
Ouverture file d'attente
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 115 -
Ouverture de la file d'attente en
mode connecté
z Unix :
int listen(int s, int backlog);
Retourne 0 ou –1 en cas d'erreur
z Windows:
int listen ( SOCKET s, int backlog );
Retourne 0 ou SOCKET_ERROR en cas d'erreur
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 116 -
Attente d'une connexion cliente
en mode connecté
z Unix :
int accept(int s, struct sockaddr *addr, int *addrlen);
Retourne une socket de service ou –1 en cas d'erreur
z Windows:
SOCKET accept ( SOCKET s, struct sockaddr FAR* addr, int FAR* addrlen );
Retourne une socket de service ou INVALID_SOCKET en cas d'échec
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 117 -
Connexion à un serveur en mode
connecté
z Unix:
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
Retourne 0 ou –1 en cas d'erreur
z Windows:
int connect ( SOCKET s, const struct sockaddr FAR* name, int namelen );
Retourne 0 ou SOCKET_ERROR en cas d'erreur
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 118 -
Lecture d'une socket en mode
connecté
z Unix:
int recv(int s, void *buf, int len, unsigned int flags);
Retourne le nombre d'octets lus ou –1 en cas d'erreur
z Windows:
int recv ( SOCKET s, char FAR* buf, int len, int flags );
Retourne le nombre d'octets lus ou SOCKET_ERROR en cas d'erreur
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 119 -
Écriture sur une socket en mode
connecté
z Unix:
int send(int s, const void *msg, int len, unsigned int flags);
Retourne le nombre d'octets écrits ou –1 en cas d'erreur
z Windows:
int send ( SOCKET s, const char FAR * buf, int len, int flags );
Retourne le nombre d'octets écrits ou SOCKET_ERROR en cas d'erreur
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 120 -
Fermeture d'une socket en
mode connecté
z La fonction close ( ) (Unix) ou closesocket ( ) (Windows) ferme la socket.
z Toute écoute de cette socket par un hôte distant (recv ( ) ) retournera 0.
z Tout envoi de données sur cette socket (send()) retournera –1.
z En mode connecté, il est conseillé d'appeler préalablement la méthode
shutdown ( ):
• Unix:
int shutdown(int s, int how);
• Windows:
int shutdown ( SOCKET s, int how );
le paramètre how peut contenir:
- 0 (SD_RECEIVE) pour interdire la lecture sur cette socket.
- 1 (SD_SEND) pour interdire l'envoi de données sur cette socket.
- 2 (SD_BOTH) pour interdire les deux.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 121 -
Manipulations simultanées de
plusieurs sockets
z Unix/Windows:
int select ( int n, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
FD_CLR (int fd, fd_set *set);
FD_ISSET (int fd, fd_set *set);
FD_SET (int fd, fd_set *set);
FD_ZERO (fd_set *set);
- 1er argument de select ( ): majorant des descripteurs sous Unix, ignoré sous
Windows
- Valeur de retour de select ( ):
. Nombre de sockets restant dans les ensembles
. 0 si la sortie est due au time out
. -1 (ou SOCKET_ERROR) en cas d'erreur
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 122 -
Options des sockets
z Unix:
int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen);
int setsockopt(int s, int level, int optname, const void*optval, socklen_t optlen);
Retourne 0 ou –1 en cas d'erreur
z Windows:
int getsockopt ( SOCKET s, int level, int optname, char FAR* optval, int FAR* optlen );
int setsockopt ( SOCKET s, int level, int optname, const char FAR * optval, int optlen );
Retourne 0 ou SOCKET_ERROR en cas d'erreur
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 123 -
Paramètres des fonctions de
gestion des options
z s:
Socket concernée par l'option
z level:
Niveau auquel s'applique l'option: SOL_SOCKET, IPPROTO_TCP, …
z optname:
Valeur de l'option en fonction du niveau choisi.
z optval:
Adresse d'une zone mémoire contenant la valeur de l'option.
z optlen:
Taille de la zone mémoire contenant la valeur de l'option.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 124 -
Exemple 1: émission d'un
datagramme UDP en broadcast
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
typedef int SOCKET ;
#define SOCKET_ERROR -1
int main ()
{
SOCKET s ;
struct sockaddr_in addr,addr_exp ;
int lg = sizeof (addr) ;
int value = 1 ; /* Valeur de l'option brodcast */
char buffer [1024] ; /* Buffer de réception du datagramme */
s = socket (PF_INET,SOCK_DGRAM,IPPROTO_UDP) ;
addr.sin_family = AF_INET ; addr.sin_port = htons (2000) ;
addr.sin_addr.s_addr = inet_addr ("192.168.16.255") ;
setsockopt (s,SOL_SOCKET,SO_BROADCAST,(char *)&value,sizeof (value)) ;
strcpy (buffer,"test broadcast") ;
sendto (s,buffer,strlen (buffer),0,&addr,lg) ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 125 -
Exemple 2: envoi de paquets en
multicast
z Serveur:
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr=mcastAddr.s_addr;
mreq.imr_interface.s_addr=htonl(INADDR_ANY);
setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP, (void *) &mreq, sizeof(mreq));
z Client:
unsigned char ttl = 1;
setsockopt(sd,IPPROTO_IP,IP_MULTICAST_TTL, &ttl,sizeof(ttl))
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 126 -
Exemple 3: Réutilisation forcée
d'un port TCP
int sockdes ;
int on = 1 ;
sockdes=socket(AF_INET,SOCK_STREAM,0);
setsockopt(sockdes,SOL_SOCKET,SO_REUSEADDR,(char *)&on,sizeof(on)) ;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 127 -
Quelques fonctions utilitaires
z Conversion d'une chaîne de caractère contenant une adresse IP en valeur 32
bits:
unsigned int inet_addr (char *str) ;
z Conversion d'une adresse IP 32 bits en chaîne de caractères:
char *inet_ntoa (struct in_addr ip) ;
z Obtention des informations sur l'association locale d'une socket:
int getsockname(int s,struct sockaddr * name ,socklen_t * namelen )
z Obtention du nom de la machine locale dans name contenant au plus length
caractères:
int gethostname (char *name,int length) ;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 128 -
Quelques fonctions utilitaires
z Lecture non bloquante d'une socket:
#include <fcntl.h>
int optSock
fcntl(sd, F_GETFL, &optSock); /* Lit options sur la socket */
optSock |= O_NDELAY; /* Définit options */
fcntl(sd, F_SETFL, &optSock); /* Applique options */
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 129 -
Remote
Procedure
Call
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 130 -
Généralités sur les RPC
z Concepts introduit par SUN MicroSystem pour l'implémentation
de la couche NFS (Network File System).
z Objectif: une application cliente doit pouvoir exécuter une
fonction sur une machine distante.
z Le programmeur est déchargé de la gestion des sockets.
z Ce concept d'informatique distribuée a servi de base à la
gestion des RMI (Remote Method Invocation), EJB (Enterprise
Java Bean) de Java et à CORBA (Common Object Request
Broker Architecture).
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 131 -
Généralités sur les RPC
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 132 -
Vision des RPC par le
programmeur
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 133 -
Vision des RPC par le
concepteur
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 134 -
RPC: côté serveur
z Les fonctions sont enregistrées auprès d'un processus portmap (TCP/111).
z Une fonction est caractérisée par un entier long, un numéro de version et un nom.
z Les entiers longs sont répertoriés ainsi (liste dans /etc/rpc sous Unix):
Réservé
0x60000000 à 0xffffffff
Réservé (Transient
0x40000000 à 0x5fffffff
Non réservé
0x20000000 à 0x3fffffff
Réservé (défini par Sun)
0x00000000 à 0x1fffffff
Description
Intervalle
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 135 -
Enregistrement des fonctions
int registerrpc (
unsigned long prog,
unsigned long vers,
unsigned long proc,
char *(*f) (),
bool_t (*xdr_arg) (),
bool_t (*xdr_res)()
) ;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 136 -
Utilisation d'une fonction
distante
int callrpc (
char *machine,
unsigned long prog,
unsigned long vers,
unsigned long proc,
bool_t (*xdr_arg)(),
char *arg,
bool_t (*xdr_res)()
char *res
) ;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 137 -
XDR: Codage des types de
données
z Problème principal des rpc: trouver un codage commun de tous
les types de données indépendant de la plate forme.
z Une bibliothèque de codage a été créée: XDR (eXternal Data
Representation).
z Nécessite le fichier d'entête: #include <rpc/xdr.h>
z Chaque type scalaire de base dispose d'une fonction de
codage de la forme:
bool_t xdr_<type> (XDR xdr, <type>argresp)
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 138 -
Codage XDR des types de base
xdr_double
double
xdr_float
float
xdr_u_long
unsigned long
xdr_long
long int
xdr_u_short
unsigned short
xdr_short
short int
xdr_u_int
unsigned int
xdr_int
int
xdr_char
char
Fonction XDR associée
TYPE C
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 139 -
Codage XDR d'une structure
struct complexe
{
float reel,imaginaire ;
} ;
bool_t xdr_complexe (XDR *xdr,struct complexe *ptr)
{
return xdr_float (xdr,&ptr->reel) && xdr_float (xdr,&ptr->imaginaire) ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 140 -
Exemple RPC: le fichier d'entête
#include <rpc/types.h>
#include <rpc/xdr.h>
struct couple
{
float e1,e2 ;
} ;
int xdr_couple () ;
struct couple *mult (struct couple *) ;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 141 -
Exemple RPC: le serveur
#include "exemple.h"
main ()
{
int rep ;
rep = registerrpc (0x33333333,1,2,mult,xdr_couple,xdr_couple) ;
if (rep < 0)
{
perror ("registerrpc") ;
exit (1) ;
}
svc_run () ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 142 -
Exemple RPC: le client
#include <stdio.h>
#include "exemple.h"
int main (int argc,char **argv)
{
struct couple don,res ;
if (argc != 2)
{
fprintf (stderr,"Usage: call machinen") ;
exit (1) ;
}
for (;;)
{
printf ("Entrer 2 reels : ") ; scanf ("%f%f",&don.e1,&don.e2) ;
if (callrpc (argv [1],0x33333333,1,2,xdr_couple,&don,xdr_couple,&res) == 0)
{
printf (" %f * %f = %fn",don.e1,don.e2,res.e1) ;
printf (" %f / %f = %fn",don.e1,don.e2,res.e2) ;
}
else fprintf (stderr,"Erreurn") ;
}
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 143 -
Exemple RPC: la fonction mult ()
#include "exemple.h"
char *mult (struct couple *p)
{
static struct couple res ;
res.e1 = p->e1 * p->e2 ;
res.e2 = p->e1 / p->e2 ;
return ( (char *) &res) ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 144 -
Exemple RPC: la conversion
XDR
#include "exemple.h"
bool_t xdr_couple (XDR *xdrp,struct couple *p)
{
return ( xdr_float (xdrp,&p->e1) && xdr_float (xdrp,&p->e2) ) ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 145 -
Le langage RPCL
z Création d'un "Remote Procedure Call Language" (RPCL) pour
simplifier l'écriture des fonctions XDR.
z C'est un langage de description des types de données à
utiliser.
z La commande rpcgen va ensuite générer:
• Toutes les fonctions xdr nécessaires.
• Les squelettes (côté client et côté serveur) qui vont rendre
transparent au programmeur l'aspect réseau et les
conversions xdr.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 146 -
Principe de fonctionnement
es.x
es.h es_clnt.c es_svc.c es_xdr.c
rpcgen
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 147 -
Syntaxe RPCL
z Le langage RPCL consiste en une série de définitions
pouvant être de 6 types différents :
• déclaration de constantes
• déclaration de types énumérés
• déclaration de structures (identique au C)
• déclaration d'unions
• déclaration de nouveaux types (typedef, identique
au C)
• déclaration de programme
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 148 -
Écriture du serveur
z Les règles à observer pour l'écriture des fonctions du serveur sont les
suivantes :
• Les noms de fonctions (définies dans es.x) doivent être suivies du
caractère "_" et du numéro de version; Si par exemple on a défini
dans es.x une fonction gettime correspondant à la version 1, le
nom de cette fonction dans le fichier proc.c sera gettime_1.
• Les fonctions n'admettent qu'un seul paramètre qui est un
pointeur sur le type déclaré dans le fichier es.x.
• La valeur de retour des fonctions est également un pointeur sur le
type déclaré dans le fichier es.x.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 149 -
Écriture du client
#include <rpc/rpc.h>
#include "es.h"
void main (int argc,char **argv)
{
CLIENT *cl ;
/* server est une chaîne de caractère contenant le nom de la machine distante
Le protocole est soit "udp", soit "tcp" */
cl = clnt_create (server,....PROG,.....VERS,protocole) ;
if (cl == NULL)
{
clnt_pcreateerror (server) ;
exit (1) ;
}
Appel de la fonction distante avec 2 paramètres :
- adresse sur le type déclaré
- variable cl
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 150 -
Syntaxe RPCL
Constantes
const <identificateur> = <integer> ;
Exemple : const MAX=8192 ;
Types énumérés
enum <identificateur>
{
enum-value-list
}
où enum-value-list représente :
enum-value , enum-value-list
où enum-value représente
identificateur = valeur
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 151 -
Syntaxe RPCL: la clause
program
program <identificateur>
{
version <identificateur>
{
type nom_fonction (type) = <valeur> ;
...
} = valeur ;
} = valeur ;
Exemple :
program TIMEPROG
{
version TIMEVERS
{
unsigned int TIMEGET (void) = 1 ;
void TIMESET (unsigned) = 2 ;
} = 1 ;
} = 0x2000000 ;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 152 -
Exemple: le fichier RPCL: add.x
struct data
{
unsigned int arg1;
unsigned int arg2;
};
typedef struct data data;
struct reponse
{
unsigned int somme;
int errno;
};
typedef struct reponse reponse;
program CALCUL
{
version VERSION_UN
{
void CALCUL_NULL(void) = 0;
reponse CALCUL_ADDITION(data) = 1;
} = 1;
} = 0x20000001;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 153 -
Génération des différents
fichiers
z La commande "rpcgen –a add.x" génère les fichiers:
• add.h fichier d'entête à laisser inchangé
• add_client.c programme client, à compléter
• add_clnt.c squelette client à laisser inchangé
• add_server.c fonctions distantes, à compléter
• add_svc.c squelette serveur, à laisser inchangé
• add_xdr.c codage xdr des types utilisés, à laisser inchangé
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 154 -
Exemple d'écriture d'une
fonction
reponse *calcul_addition_1(data *argp, struct svc_req * rqstp)
{
static reponse result;
result.somme = argp->arg1 + argp->arg2 ;
return (&result);
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 155 -
Exemple: la fonction à
enregistrer
#include <stdio.h>
char **essai_1 (char **chaine)
{
static char *buffer ;
if (buffer == NULL)
{
buffer = calloc (10,sizeof (char)) ;
}
strncat (buffer,"Bonjourn",8) ;
return &buffer ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 156 -
Exemple: le client
#include <rpc/rpc.h>
#include "es.h"
void main (int argc,char **argv)
{
CLIENT *cl ;
char *buffer ;
char **result ;
buffer = (char *) calloc (20,sizeof (char)) ;
cl = clnt_create ("e3000",MESSAGEPROG,MESSAGEVERS,"tcp") ;
if (cl == NULL)
{
perror ("Connexion client") ;
exit (1) ;
}
strncpy (buffer,"essai ",5) ;
result = essai_1(&buffer) ;
printf ("%sn",*result) ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 157 -
La bibliothèque
libsdl
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 158 -
Bibliothèque SDL
z Tentative d'uniformiser les API Windows/Linux sur les thèmes:
• audio
• vidéo
• threads
• timers
• …
z Logiciels domaine public: http://www.libsdl.org
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 159 -
Exemple programmation thread
int main (int argc,char **argv)
{
const int progeny = 5;
SDL_Thread *kids[progeny];
int i, lots;
lock = SDL_CreateMutex();
for ( i=0; i<progeny; ++i ) {
kids[i] = SDL_CreateThread(thread_func, (void *)i);
}
SDL_Delay(5*1000);
SDL_mutexP(lock);
printf("On arrete les threadsn"); fin = 1;
SDL_mutexV(lock);
for ( i=0; i<progeny; ++i ) {
SDL_WaitThread(kids[i], &lots);
printf("Thread %d a utilise le mutex %d foisn", i,
lots+1);
}
SDL_DestroyMutex(lock);
return 0 ;
}
#include <stdio.h>
#include "SDL.h"
#include "SDL_thread.h"
#include "SDL_mutex.h"
int potty = 0;
int fin;
SDL_mutex *lock;
int thread_func(void *data)
{
int num = (int) data;
int compteur = 0;
while ( fin == 0 ) {
printf ("Thread %d, je prends le mutexn",num) ;
SDL_mutexP(lock);
printf ("Thread %d, j'ai pris le mutexn",num) ;
SDL_Delay (1000) ;
printf ("Thread %d, je rends le mutexn",num) ;
SDL_mutexV(lock); compteur += 1 ;
}
printf("Fin Thread %dn",num);
return(compteur);
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 160 -
Exemple d'utilisation d'un mutex
int main (int argc,char **argv)
{
const int progeny = 5;
SDL_Thread *kids[progeny];
SDL_mutex *lock;
int i, lots;
lock = SDL_CreateMutex();
gotta_go = 1;
for ( i=0; i<progeny; ++i ) {
kids[i] = SDL_CreateThread(thread_func, lock);
}
SDL_Delay(5*1000); SDL_mutexP(lock);
printf("Everybody done?n"); gotta_go = 0;
SDL_mutexV(lock);
for ( i=0; i<progeny; ++i ) {
SDL_WaitThread(kids[i], &lots);
printf("Thread %d used the potty %d timesn", i+1,
lots);
}
SDL_DestroyMutex(lock); return 0 ;
}
#include <stdio.h>
#include "SDL.h"
#include "SDL_thread.h"
#include "SDL_mutex.h"
int potty = 0;
int gotta_go;
int thread_func(void *data)
{
SDL_mutex *lock = (SDL_mutex *)data;
int times_went = 0 ;
while ( gotta_go ) {
SDL_mutexP(lock); ++potty;
printf("Thread %d using the pottyn", SDL_ThreadID());
if ( potty > 1 ) {
printf("potty already used!n");
}
-- p
otty; SDL_mutexV(lock); ++times_went;
}
printf("okn");
return(times_went);
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 161 -
Programmation
réseau IPv6
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 162 -
La programmation IPv6
z L'interface de programmation IPv6 est
définie par les RFC 2553 et 2292.
z Ce qui a changé:
• Les structures d'adresse.
• L'interface socket.
• Les fonctions de conversions entre noms et
adresses.
• Les fonctions de conversion d'adresses.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 163 -
Les structures d'adresses
z Une nouvelle famille d'adresses AF_INET6 et une
nouvelle famille de protocole PF_INET6 ont été définies
dans <sys/socket.h>.
z Pour des raisons de compatibilité, ces deux constantes
sont égales:
#define PF_INET6 AF_INET6
z Une adresse IPv6 est contenue dans la structure:
struct in6_addr
{
uint8_t s6_addr[16]; /* IPv6 address */
};
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 164 -
Les structures d'adresses
z La structure in6_addr peut également être définie
par:
struct in6_addr
{
union
{
uint8_t _S6_u8[16];
uint32_t _S6_u32[4];
uint64_t _S6_u64[2];
} _S6_un;
};
#define s6_addr _S6_un._S6_u8
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 165 -
La structure sockaddr_in6
z Structure analogue à la structure sockaddr_in d'IPv4.
z Il existe deux implémentations de cette structure:
• Implémentation d'Unix 4.3BSD:
struct sockaddr_in6
{
sa_family_t sin6_family; /* AF_INET6 (champ sur 16 bits) */
in_port_t sin6_port; /* transport layer port # */
uint32_t sin6_flowinfo; /* IPv6 traffic class & flow info */
struct in6_addr sin6_addr; /* IPv6 address */
uint32_t sin6_scope_id; /* set of interfaces for a scope */
};
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 166 -
La structure sockaddr_in6
• Implémentation d'Unix 4.4BSD:
struct sockaddr_in6
{
uint8_t sin6_len; /* length of this struct */
sa_family_t sin6_family; /* AF_INET6 (champ sur 8 bits)*/
in_port_t sin6_port; /* transport layer port # */
uint32_t sin6_flowinfo; /* IPv6 flow information */
struct in6_addr sin6_addr; /* IPv6 address */
uint32_t sin6_scope_id; /* set of interfaces for a scope */
};
z Les systèmes qui implémentent la version 4.4BSD définissent une
constante SIN6_LEN dans le fichier d'entête <netinet/in.h>.
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 167 -
L'adresse "wildcard"
z En IPv4, la constante INADDR_ANY est utilisée par
une application pour laisser au système le choix de
l'adresse source.
z En IPv6, il y a deux possibilités:
• Utilisation d'une constante au moment de la déclaration:
struct in6_addr anyaddr = IN6ADDR_ANY_INIT;
• Utilisation d'une variable externe:
extern const struct in6_addr in6addr_any;
sin6.sin6_addr = in6addr_any;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 168 -
L'adresse de "loopback"
z En IPv4, l'adresse de "loopback" est définie par la
constante INADDR_LOOPBACK.
z En IPv6, il y a deux possibilités:
• Utilisation d'une constante au moment de la déclaration:
struct in6_addr loopbackaddr = IN6ADDR_LOOPBACK_INIT;
• Utilisation d'une variable externe:
extern const struct in6_addr in6addr_loopback;
sin6.sin6_addr = in6addr_loopback;
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 169 -
L'interface socket
z La fonction socket () utilise le même schéma qu'en IPv4:
sock = socket (PF_INET6,SOCK_DGRAM,0) ;
sock = socket (PF_INET6,SOCK_STREAM,0) ;
z Les autres fonctions de l'interface socket sont inchangées,
moyennant le transfert d'une adresse de type struct
sockaddr_in6.
z Principales fonctions inchangées:
bind (), connect (), send (), sendto (), accept (), recv (), recvfrom (),
getsockname (), getpeername ().
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 170 -
Les fonctions de conversion
entre noms et adresses
z Les fonctions gethostbyname (), gethostbyaddr (),
getservbyname (), getservbyport () ont été remplacées par
deux fonctions: getaddrinfo () et getnameinfo ():
int getaddrinfo ( const char *nodename, const char *servname,
const struct addrinfo *hints, struct addrinfo **res);
int getnameinfo ( const struct sockaddr *sa, socklen_t salen,
char *host, size_t hostlen, char *serv, size_t servlen, int flags);
z Les structures addrinfo sont allouées dynamiquement; il faut les
désallouer après utilisation:
void freeaddrinfo(struct addrinfo *ai);
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 171 -
La structure "addrinfo"
struct addrinfo
{
int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
int ai_family; /* PF_xxx */
int ai_socktype; /* SOCK_xxx */
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
size_t ai_addrlen; /* length of ai_addr */
char *ai_canonname; /* canonical name for nodename */
struct sockaddr *ai_addr; /* binary address */
struct addrinfo *ai_next; /* next structure in linked list */
};
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 172 -
Les fonctions de conversion
numériques d'adresses
z Les deux fonctions inet_addr () et inet_ntoa ()
convertissent des adresses IPv4 entre une représentation
binaire et une représentation textuelle.
z Les fonctions équivalentes pour IPv6/IPv4 sont:
int inet_pton(int af, const char *src, void *dst);
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
z Ces fonctions ne sont pas supportées par winsock; on
peut utiliser en remplacement WSAAddressToString() et
WSAStringToAddress ().
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 173 -
Exemple de conversion
d'adresse
#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
int main (int argc,char **argv)
{
struct addrinfo hints ;
struct addrinfo *res ;
char str_addr [INET6_ADDRSTRLEN] ;
memset (&hints,0,sizeof (struct addrinfo)) ;
hints.ai_family = PF_INET6 ;
if (getaddrinfo ("www.crihan.fr",NULL,&hints,&res) == 0)
{
struct in6_addr *src = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr ;
if (inet_ntop (AF_INET6,src,str_addr,sizeof (str_addr)) != 0)
{
printf ("Adresse IPv6 = %sn",str_addr) ;
}
freeaddrinfo (res) ;
}
else printf ("Adresse non resoluen") ;
}
Résultat affiché:
Adresse IPv6 = ::2001:660:7401:211:0:0
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 174 -
Même exemple sous Windows
#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>
int main (int argc, char **argv [])
{
WSADATA wsadata ;
if (WSAStartup (MAKEWORD (2,2),&wsadata) != 0) { fprintf (stderr,"Erreur dlln") ; return 1 ; }
struct addrinfo hints ; struct addrinfo *res ;
memset (&hints,0,sizeof (struct addrinfo)) ;
hints.ai_family = PF_INET6 ; hints.ai_socktype = SOCK_STREAM ;
if (getaddrinfo ("www.crihan.fr",NULL,&hints,&res) == 0)
{
char dest [INET6_ADDRSTRLEN] ;
DWORD lg_dest = INET6_ADDRSTRLEN ;
if (WSAAddressToString (res->ai_addr,res->ai_addrlen,NULL,dest,&lg_dest) == 0)
{
printf ("adresse IPv6 = %sn",dest) ;
}
freeaddrinfo (res) ;
}
WSACleanup () ;
}
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 175 -
Annexes
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 176 -
Entête IP
32 bits
Version IHL Type Service Longueur Totale
Identification Flags Décalage Fragment
TTL Protocole Contrôle entête
Adresse Source
Adresse Destination
Options Remplissage
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 177 -
Entête TCP
32 bits
Port source Port destination
Numéro de séquence
Numéro d'acquittement
Long
entête
TCP
U A P R S F
R C S S Y I
G K H T N N
Taille de la fenêtre
Total de contrôle Pointeur d'urgence
Options (0, 1 ou plusieurs mots de 32 bits
Données (optionnelles)
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 178 -
Entête UDP
32 bits
Port source Port destination
Longueur UDP Total de contrôle UDP
- Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 179 -
Entête IPv6
Adresse source (16 octets)
Adresse destination (16 octets)
Ver
sion
Pri Etiquette de flot
Longueur de charge utile En-tête suivant Nb max de
sauts
32 bits

Contenu connexe

Similaire à ProcessusReseaux.pdf

Etude DéTailléé de la pile réseau sous GNU Linux
Etude DéTailléé de la pile réseau sous GNU LinuxEtude DéTailléé de la pile réseau sous GNU Linux
Etude DéTailléé de la pile réseau sous GNU Linux
Thierry Gayet
 

Similaire à ProcessusReseaux.pdf (20)

SdE 4: Processus
SdE 4: ProcessusSdE 4: Processus
SdE 4: Processus
 
Formation python
Formation pythonFormation python
Formation python
 
Asyncio: offrez des tulipes à vos entrées sorties asynchrones
Asyncio: offrez des tulipes à vos entrées sorties asynchronesAsyncio: offrez des tulipes à vos entrées sorties asynchrones
Asyncio: offrez des tulipes à vos entrées sorties asynchrones
 
Traitement des données massives (INF442, A2)
Traitement des données massives (INF442, A2)Traitement des données massives (INF442, A2)
Traitement des données massives (INF442, A2)
 
Etude DéTailléé de la pile réseau sous GNU Linux
Etude DéTailléé de la pile réseau sous GNU LinuxEtude DéTailléé de la pile réseau sous GNU Linux
Etude DéTailléé de la pile réseau sous GNU Linux
 
Reu 2014 automne
Reu 2014 automneReu 2014 automne
Reu 2014 automne
 
kaid_nhek
kaid_nhekkaid_nhek
kaid_nhek
 
Meetup Systemd vs sysvinit
Meetup Systemd vs sysvinitMeetup Systemd vs sysvinit
Meetup Systemd vs sysvinit
 
Ed2 corrige 2
Ed2 corrige 2Ed2 corrige 2
Ed2 corrige 2
 
Comment développer un serveur métier en python/C++
Comment développer un serveur métier en python/C++Comment développer un serveur métier en python/C++
Comment développer un serveur métier en python/C++
 
CI, CD, pipelines, conteneurs : la cohabitation est elle possible ?
CI, CD, pipelines, conteneurs : la cohabitation est elle possible ?CI, CD, pipelines, conteneurs : la cohabitation est elle possible ?
CI, CD, pipelines, conteneurs : la cohabitation est elle possible ?
 
C3 - Langage C - ISIMA 1 - Troisieme partie
C3 - Langage C - ISIMA 1 - Troisieme partieC3 - Langage C - ISIMA 1 - Troisieme partie
C3 - Langage C - ISIMA 1 - Troisieme partie
 
Interface texte plein écran en Go avec TView
Interface texte plein écran en Go avec TViewInterface texte plein écran en Go avec TView
Interface texte plein écran en Go avec TView
 
SdE2 - Planification, IPC
SdE2 - Planification, IPCSdE2 - Planification, IPC
SdE2 - Planification, IPC
 
Boot
BootBoot
Boot
 
Sockets
SocketsSockets
Sockets
 
Cours de C++ / Tronc commun deuxième année ISIMA
Cours de C++ / Tronc commun deuxième année ISIMACours de C++ / Tronc commun deuxième année ISIMA
Cours de C++ / Tronc commun deuxième année ISIMA
 
LINUX : Système, administration et services réseaux
LINUX : Système, administration et services réseauxLINUX : Système, administration et services réseaux
LINUX : Système, administration et services réseaux
 
Introduction a la compilation Aperçu de la compilation / Assembleur MIPS - C1
Introduction a la compilation  Aperçu de la compilation / Assembleur MIPS - C1Introduction a la compilation  Aperçu de la compilation / Assembleur MIPS - C1
Introduction a la compilation Aperçu de la compilation / Assembleur MIPS - C1
 
C1 linux et intro c
C1 linux et intro cC1 linux et intro c
C1 linux et intro c
 

Dernier (6)

pdfcoffee.com_4-production-fond-des-puits-completion-pdf-free.pdf
pdfcoffee.com_4-production-fond-des-puits-completion-pdf-free.pdfpdfcoffee.com_4-production-fond-des-puits-completion-pdf-free.pdf
pdfcoffee.com_4-production-fond-des-puits-completion-pdf-free.pdf
 
le probleme de la planification JSP exposee (2) (2).pptx
le probleme de la planification JSP exposee (2) (2).pptxle probleme de la planification JSP exposee (2) (2).pptx
le probleme de la planification JSP exposee (2) (2).pptx
 
mémoire genie civil presenté lors de la soutenance de mémoire
mémoire genie civil presenté lors de la soutenance de mémoiremémoire genie civil presenté lors de la soutenance de mémoire
mémoire genie civil presenté lors de la soutenance de mémoire
 
JTC 2024 Bâtiment et Photovoltaïque.pdf
JTC 2024  Bâtiment et Photovoltaïque.pdfJTC 2024  Bâtiment et Photovoltaïque.pdf
JTC 2024 Bâtiment et Photovoltaïque.pdf
 
Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024
Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024
Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024
 
Algo II: les files cours + exercices corrigés
Algo II: les files cours + exercices corrigésAlgo II: les files cours + exercices corrigés
Algo II: les files cours + exercices corrigés
 

ProcessusReseaux.pdf

  • 1. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 1 - Programmation système et réseau sous Windows et Unix Patrick Ducrot dp@ensicaen.fr
  • 2. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 2 - Plan du document Description des processus …………………………………………………………………………………………………………………………………… 3 Gestion des processus et communication par tube sous Unix ……………………………………………… 9 Gestion de processus et communication par tube sous Windows ………………………………………… 27 Synchronisation de processus ………………………………………………………………………………………………………………………… 43 Les sémaphores sous Unix …………………………………………………………………………………………………………………………………… 46 Les sémaphores sous Windows …………………………………………………………………………………………………………………………… 50 Les threads ……………………………………………………………………………………………………………………………………………………………………… 55 Les threads sous Unix …………………………………………………………………………………………………………………………………………… 60 Les threads sous Windows …………………………………………………………………………………………………………………………………… 63 Synchronisation de threads ………………………………………………………………………………………………………………………………… 67 Synchronisation de threads sous Unix ……………………………………………………………………………………………………… 70 Synchronisation de threads sous Windows ……………………………………………………………………………………………… 79 Programmation réseau ………………………………………………………………………………………………………………………………………………… 89 Remote Procedure Call ……………………………………………………………………………………………………………………………………………… 129 La bibliothèque SDL …………………………………………………………………………………………………………………………………………………… 157 Programmation réseau IPv6 …………………………………………………………………………………………………………………………………… 161
  • 3. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 3 - Description des processus
  • 4. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 4 - Définition d’un processus z Un processus correspond à l’exécution d’une tâche. z Aspect dynamique d’un programme. z Un système d’exploitation doit exécuter « simultanément » plusieurs processus. z Chaque processus est composé en mémoire: • Un espace pour le code • Un espace pour les données • Un espace pour la pile d’exécution
  • 5. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 5 - Définition des processus P 1 P 2 P 3 P 4 P 6 P 5 Pile d'exécution Données Code Hiérarchie des processus Structure d’un processus
  • 6. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 6 - État d’un processus z Le passage d’un processus à un autre est assuré par un ordonnanceur. Élu Prêt Bloqué
  • 7. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 7 - Descripteurs d’Entrée/Sortie processus stdin 0 stdout 1 stderr 2
  • 8. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 8 - Création de processus z Fonctionnement très différent entre Windows et Unix: Unix Windows exec () fork () CreateProcess ()
  • 9. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 9 - Gestion de processus sous UNIX
  • 10. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 10 - Création d’un processus sous Unix z Sous Unix, un processus peut se dupliquer: pid_t fork(void); z La fonction renvoie: • -1 si erreur • 0 pour le processus fils • >0 pour le processus père (Process IDentification)
  • 11. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 11 - Duplication de processus UNIX void main () { if (fork () != 0) { printf ("Je suis le peren") ; } else { printf ("je suis le filsn") ; } }
  • 12. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 12 - État après le fork () if (fork () != 0) { printf ("Je suis le peren") ; } else { printf ("je suis le filsn") ; } if (fork () != 0) { printf ("Je suis le peren") ; } else { printf ("je suis le filsn") ; } Exécution « simultanée » Père Fils
  • 13. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 13 - Invocation d’un programme existant z L'invocation d'un programme existant ne peut se faire que par le recouvrement du code du processus appelant grâce à une des fonctions de la famille exec. z D’où l’intérêt voire la nécessité de dupliquer préalablement le processus.
  • 14. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 14 - La famille de fonctions exec int execl (char *path,char *arg0,…,char *argn,NULL) ; int execv (char *path,char *argv []) ; int execle (char *path, char *arg0,…,char *argn,NULL,char *envp[]) ; int execve (char *path,char *argv [], char *envp []) ; int execlp (char *file,char *arg0,…,char argn,NULL) ; int execvp (char *file,char *argv []) ;
  • 15. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 15 - Exemple exec #include <stdio.h> void main () { if ( fork () != 0) { printf ("je suis le pere, je continue icin") ; } else { printf ("fils: je me transformen") ; execl ("/bin/date","date",NULL) ; } } père /bin/date
  • 16. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 16 - Fin d’un processus z Un processus s’arrête lorsque: • Il n’a plus d’instruction à exécuter • Il exécute un appel à la fonction void exit (int status) ; z Lorsqu’un processus fils est terminé, celui-ci sera retiré de la table des processus si: • Le père acquitte la fin du processus fils par un appel à la fonction: int wait(int *code_de_sortie) ; • Le père ignore la fin des processus fils par un appel à la fonction: signal (SIGCHLD,SIG_IGN) ;
  • 17. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 17 - Gestion de signaux z Un signal permet de dérouter l'exécution d'un processus. z A réception d'un signal un processus peut: • se terminer (comportement par défaut) • l'ignorer • exécuter une fonction particulière z Un signal peut être envoyé par: • une commande shell: kill –num_signal PID • par programmation int kill (int pid, int signal) ;
  • 18. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 18 - Quelques signaux Unix signal émis par un fils qui se termine à son père 20 SIGCLD signal d’interruption radicale 9 SIGKILL ^ 3 SIGQUIT ^C 2 SIGINT signal émis lors d’une déconnexion 1 SIGUP Commentaires No signal Nom du signal
  • 19. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 19 - Détournement d'un signal z Un processus peut détourner les signaux reçus et modifier son comportement par l’appel de la fonction : void (*signal(int signal, void (*fonction)(int))) le deuxième argument pouvant prendre les valeurs: Le processus exécutera fonction, définie par l’utilisateur, à l’arrivée de l’interruption n. Il reprendra ensuite au point où il a été interrompu void fonction(int n) le processus rétablira son comportement par défaut lors de l’arrivée de l’interruption (la terminaison) SIG_DFL le processus ignorera l’interruption correspondante SIG_IGN Action Nom
  • 20. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 20 - Exemple détournement signal #include <stdio.h> #include <sys/signal.h> void detourne (int num_signal) { printf ("signal num %dn",num_signal) ; } void main () { signal (SIGINT,detourne) ; while (1) sleep (10) ; }
  • 21. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 21 - Communication par tube anonyme z 2 processus disposant d'un lien de parenté peuvent échanger de l'information par l'intermédiaire d'un tube anonyme. père fils Échange d'information
  • 22. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 22 - Les tubes anonymes z Le support de communication est le système de fichier z La communication est en mode caractère. z Création d'un tube anonyme: int p [2] ; pipe (p) ; p [0] descripteur en lecture p[1] descripteur en écriture p [1] p [0]
  • 23. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 23 - Les tubes anonymes - Lecture/Ecriture dans un tube anonyme : int read (int desc, char *buf, int nb) int write (int desc, char *buf, int nb) - Fermeture d'un descripteur void close (int desc)
  • 24. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 24 - Les tubes nommés z Les tubes nommés portent un nom ;) z Ils permettent à deux processus sans lien de parenté de s’échanger de l’information. Processus A Processus B Tube nommé
  • 25. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 25 - Tubes nommés z Création d'un tube nommé avec une commande shell mkfifo tube z Ouverture/Lecture/Ecriture/Fermeture int open (char *file,int mode,int droits) int read (int desc,char *buf,int nb) int write (int desc,char *buf,int nb) void close (desc)
  • 26. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 26 - Duplication de descripteurs - Un descripteur de fichier peut être dupliqué vers une entrée disponible - Duplication d’un descripteur sur le plus petit descripteur disponible int dup (int desc) - Duplication d’un descripteur vers un descripteur spécifié (avec éventuellement fermeture de celui-ci) int dup2 (int desc1, int desc2)
  • 27. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 27 - Gestion de processus sous Windows
  • 28. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 28 - Création de processus sous Windows z Lorsqu'un processus sous Windows est créé, son premier thread (thread primaire) est créé automatiquement par le système. z Le thread primaire peut créer d'autres threads qui peuvent à leur tour en créer d'autres. z Un thread quelconque peut créer un processus par un appel à la fonction CreateProcess () z Rôle de CreateProcess () : • Crée un espace d'adressage virtuel pour ce processus • Charge le processus dans cet espace • Définit le thread primaire pour ce processus • Lance l’exécution du thread primaire z CreateProcess renvoie TRUE si la création est un succès
  • 29. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 29 - La fonction CreateProcess () BOOL CreateProcess ( LPCTSTR lpApplicationName, LPCTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation );
  • 30. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 30 - Paramètres de CreateProcess () 1/5 z lpApplicationName : identifie le nom du fichier exécutable qui peut se trouver : - Dans le répertoire courant, dans le répertoire SYSTEM et dans les répertoires spécifiés dans la commande PATH - On peut passer NULL : dans ce cas, on considère que le nom du fichier exécutable est le 1ier élément (jusqu'au premier espace) du paramètre lpCommandLine z lpCommandLine : spécifie les arguments de la ligne de commande à passer au processus incluant le nom de l'exécutable si lpApplicationName vaut NULL.
  • 31. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 31 - Paramètres de CreateProcess () 2/5 z lpProcessAttributes et lpThreadAttributes : : pointent sur une structure SECURITY_ATTRIBUTES qui indique qui a le droit de se partager l'objet et si d'autres processus ont le droit de le modifier; On peut passer NULL, dans ce cas, le processus et le thread reçoivent le descripteur par défaut et personne ne pourra en hériter z bInheritHandles : indique si l'identificateur de l'objet processus/thread est héritant. En général un objet possède des Id's différents lorsqu'il est utilisé dans des processus différents. Toutefois, Windows permet aux Id's d'être hérités
  • 32. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 32 - Paramètres de CreateProcess () 3/5 z dwCreationFlags : identifie des indicateurs (séparés par des OU logiques) qui affectent la création Exemples : CREATE_SUSPENDED CREATE_NEW_CONSOLE … z lpEnvironment : pointe sur un bloc de mémoire contenant les chaînes d'environnement utilisées par le processus. Le plus souvent on passe NULL, ce qui signifie que le processus enfant emploie les mêmes chaînes d'environnement que son père
  • 33. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 33 - Paramètres de CreateProcess () 4/5 z lpCurrentDirectory : permet au processus appelant CreateProcess d'indiquer à Windows le nom du répertoire courant pour le nouveau processus. Si on passe NULL, le répertoire courant est le même que celui de l'application l'ayant créée z lpStartupInfo : pointe sur une structure STARTUPINFO qui contient des membres que l'on peut affecter, soit pour des applications console ou pour des applications graphiques ou les deux, pour le lancement
  • 34. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 34 - Paramètres de CreateProcess () 5/5 z lpProcessInformation : pointe sur une structure PROCESS_INFORMATION que CreateProcess remplira avant de retourner ; la structure a l'aspect suivant : typedef struct _PROCESS_INFORMATION { HANDLE hProcess; HANDLE hThread; DWORD dwProcessId; DWORD dwThreadId; } PROCESS_INFORMATION;
  • 35. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 35 - Exemple de CreateProcess #include <windows.h> void main () { STARTUPINFO si ; PROCESS_INFORMATION pi ; GetStartupInfo (&si) ; // Initialisation de la STARTUPINFO CreateProcess (NULL, "notepad", NULL,NULL, FALSE, 0,NULL,NULL, &si,&pi) ; }
  • 36. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 36 - La structure STARTUPINFO typedef struct STARTUPINFO { DWORD cb; // taille de la structure LPTSTR lpReserved; // doit être laissé à NULL LPTSTR lpDesktop; // nom de l'objet bureau LPSTR lpTitle; // légende pour le titre de la fenêtre (mode console) DWORD dwX; // coin supérieur gauche de la fenêtre DWORD dwY; DWORD dwXSize; // largeur nouvelle fenêtre DWORD dwYSize; // hauteur nouvelle fenêtre DWORD dwXCountChars; // largeur nouvelle fenêtre console DWORD dwYCountChars; // hauteur nouvelle fenêtre console DWORD dwFillAttribute; // couleur texte et fond pour la console DWORD dwFlags; // activation des champs de la structure WORD wShowWindow; // valeur de iCmdShow WORD cbReserved2; // zéro LPBYTE lpReserved2; // NULL HANDLE hStdInput; // handle d'entrée standard HANDLE hStdOutput; // handle de sortie standard HANDLE hStdError; // handle d'erreur standard } STARTUPINFO, *LPSTARTUPINFO ;
  • 37. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 37 - Création/Fermeture d'un tube anonyme sous Windows BOOL CreatePipe ( PHANDLE hRead, // Handle de lecture PHANDLE hWrite, // Handle d'écriture LPSECURITY_ATTRIBUTES lpPipeAttributes, // Privilège d'accès DWORD nSize) // taille du tube, valeur par défaut si 0 typedef struct _SECURITY_ATTRIBUTES { DWORD nLength; // Doit contenir la taille de la structure LPVOID lpSecurityDescriptor; // Paramètre de sécurité BOOL bInheritHandle; // TRUE si le pipe doit être transmis par héritage } SECURITY_ATTRIBUTES; BOOL CloseHandle( HANDLE hObject ) ; // Handle à fermer
  • 38. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 38 - Utilisation d'un tube anonyme sous Windows BOOL ReadFile ( HANDLE hFile, // handle de lecture LPVOID lpBuffer, // adresse de réception des données DWORD nNumberOfBytesToRead, // Nombre d'octets réservés LPDWORD lpNumberOfBytesRead, // adresse de réception du nombre d'octets lus LPOVERLAPPED lpOverlapped // lecture asynchrone ); BOOL WriteFile ( HANDLE hFile, // handle d'écriture LPVOID lpBuffer, // Adresse des données à écrire DWORD nNumberOfBytesToWrite, // nombre d'octets à écrire LPDWORD lpNumberOfBytesWritten, // adresse de réception du nombre d'octets à écrire LPOVERLAPPED lpOverlapped // Ecriture asynchrone );
  • 39. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 39 - Tubes nommés sous Windows z Concept très évolué sous Windows: • Un serveur (créateur du tube nommé) peut avoir plusieurs clients (instance) • Les clients et le serveur peuvent être sur des machines distinctes (moyennant les problèmes de droits d'accès). Serveur Clients
  • 40. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 40 - Création d'un tube nommé sous Windows HANDLE CreateNamedPipe( LPCTSTR lpName, // Nom du tube: .pipenom DWORD dwOpenMode, // Mode d'ouverture du fichier DWORD dwPipeMode, // Mode d'ouverture spécifique au tube DWORD nMaxInstances, // Nombre maximal d'instances DWORD nOutBufferSize, // Taille du buffer de sortie DWORD nInBufferSize, // Taille du buffer d'entrée DWORD nDefaultTimeOut, // Timeout si un client appelle WaitNamedPipe LPSECURITY_ATTRIBUTES lpSecurityAttributes // Privilège d'accès );
  • 41. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 41 - Exemple tube nommé sous Windows tube = CreateNamedPipe (".pipeServeurDessin", PIPE_ACCESS_DUPLEX | FILE_FLAG_WRITE_THROUGH, PIPE_TYPE_MESSAGE | PIPE_WAIT, 1,0,0,0,NULL) ; if (tube == INVALID_HANDLE_VALUE) { LPVOID lpMsgBuf;FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL );// Display the string. ::MessageBox( NULL, (char *)lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION ); LocalFree( lpMsgBuf ); MessageBox ("Le tube de communication n'a pas pu être créé","Erreur",MB_ICONERROR | MB_OK) ; PostQuitMessage (0) ; }
  • 42. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 42 - Connexion à un tube nommé sous Windows HANDLE CreateFile ( LPCTSTR lpFileName, // Nom du tube DWORD dwDesiredAccess, // Mode d'accès (lecture/écriture) // GENERIC_READ si le tube a été créé avec PIPE_ACCESS_OUTBOUND //GENERIC_WRITE si le tube a été créé avec PIPE_ACCESS_INBOND // GENERIC_WRITE | GENERIC_READ si duplex DWORD dwShareMode, // 0 pour interdire le partage du tube avec d'autres processus LPSECURITY_ATTRIBUTES lpSecurityAttributes, // Privilège d'accès DWORD dwCreationDistribution, // OPEN_EXISTING puisqu'on ouvre un tube existant DWORD dwFlagsAndAttributes, //FILE_FLAG_WRITE_THROUGH pour une écriture synchrone HANDLE hTemplateFile // Pas de signification pour les tubes );
  • 43. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 43 - Synchronisation de processus
  • 44. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 44 - Synchronisation de processus z Plusieurs processus peuvent entrer en conflit pour l'accès à une ressource: • Accès en écriture à un fichier texte. • Accès à de la mémoire partagée. • … z On peut souhaiter limiter le nombre d'accès simultanés à une ressource: • Accès en lecture à un fichier texte. • …
  • 45. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 45 - Définition d'un sémaphore z Les sémaphores est un concept introduit par Djikstra. z Un sémaphore est une valeur entière, initialisée avec le nombre d'accès simultanés autorisés, associée à 2 fonctions atomiques (P (sem) et V (sem) ) pour acquérir et rendre un accès et une file d'attente. z Acquérir un accès revient à décrémenter la valeur du sémaphore; si la valeur devient <0, le processus est placé en file d'attente. z Rendre un accès revient à incrémenter la valeur du sémaphore et réveiller un processus si la valeur est <= 0.
  • 46. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 46 - Les Sémaphores sous Unix
  • 47. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 47 - Les sémaphores sous Unix z Unix gère les sémaphores à la norme "Posix" (proche de la définition des sémaphores de Djikstra) qui seront vus au chapitre des threads et des sémaphores "Unix" qui sont des tableaux de sémaphores. z Les types et prototypes nécessaires pour manipuler les sémaphores "Unix" sont: #include <sys/ipc.h> #include <sys/sem.h>
  • 48. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 48 - Manipulations de sémaphores sous Unix (1/2) z Création: int semget(key_t clé, int NombreSéma, int flag); Exemple: cle = ftok("nom_fichier_existant", 'A'); idSema = semget(cle, 5, IPC_CREAT | 0600); // Création d'un tableau de 5 sémaphores // avec des droits d'accès exclusifs. z Manipulation (initialisation, consultation, destruction): int semctl(int idSema, int NombreSéma, int commande, ushort semarray); Exemple: semctl (semid,0,SETVAL,1) ; // initialisation à 1 du sémaphore numéro 0
  • 49. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 49 - Manipulations de sémaphores sous Unix (2/2) z Acquisition/Libération: int semop(int idSema, struct sembuf *sops, size_t NbOpérat) ; Exemple: struct sembuf op ; op.sem_num = 0 ; // Indice du sémaphore au sein du tableau de sémaphore op.sem_op = 1 ; // 1 pour acquisition, -1 pour libération op.sem_flg = 0 ; // 0 pour acquisition bloquante semop (semid,&op,1) ; // Acquisition, si la valeur est < 0, la fonction sera bloquante
  • 50. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 50 - Les sémaphores sous Windows
  • 51. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 51 - Création sémaphore Windows z Création d'un sémaphore: HANDLE CreateSemaphore ( LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName ); z Ouverture d'un sémaphore existant: HANDLE OpenSemaphore ( DWORD dwDesiredAccess, // SEMAPHORE_ALL_ACCESS // SEMAPHORE_MODIFY_STATE BOOL bInheritHandle, LPCTSTR lpName );
  • 52. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 52 - Utilisation sémaphore Windows z Demande d'un accès: DWORD WaitForSingleObject( HANDLE hHandle, // Handle du sémaphore DWORD dwMilliseconds // time-out en millisecondes ); z Restitution d'accès: BOOL ReleaseSemaphore ( HANDLE hSemaphore, // handle du sémaphore LONG lReleaseCount, // Valeur à ajouter au sémaphore LPLONG lpPreviousCount // Récupération de la valeur // précédente ) ;
  • 53. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 53 - Exemple (1/2) #include <windows.h> #include <stdio.h> void main () { HANDLE sem ; LONG previous ; int i ; sem= CreateSemaphore (NULL,1,1,"semaphore") ; if (sem == NULL) { exit (1) ; } for (i = 0 ; i != 10 ; i++) { WaitForSingleObject (sem,INFINITE) ; printf ("A: j'ai prisn") ; Sleep (5000) ; printf ("A: je liberen") ; ReleaseSemaphore (sem,1,&previous) ; } }
  • 54. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 54 - Exemple (2/2) #include <windows.h> #include <stdio.h> void main () { HANDLE sem ; LONG previous ; int i ; sem = OpenSemaphore (SEMAPHORE_ALL_ACCESS,FALSE,"semaphore") ; if (sem == NULL) { exit (1) ; } for (i = 0 ; i != 10 ; i++) { WaitForSingleObject (sem,INFINITE) ; printf ("B: j'ai prisn") ; Sleep (3000) ; printf ("B: je liberen") ; ReleaseSemaphore (sem,1,&previous) ; } }
  • 55. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 55 - Les threads
  • 56. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 56 - Définition d'un Thread z Un thread est une unité d'exécution au sein d'un processus. z Un processus peut être composé de plusieurs threads. z Des quantums de temps seront alloués à chacun des threads, en fonction de leur priorité. z Tous les threads d'un même processus partagent le même espace mémoire. z L'échange d'informations entre deux threads est plus rapide qu'entre deux processus mais peut engendrer des conflits d'accès aux ressources.
  • 57. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 57 - Définition d'un thread th1 th2 th3 Processus 1 Processus 2 th1 th2 thread
  • 58. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 58 - Similitudes threads Unix/Windows z Chaque thread dispose d'un point d'entrée (fonction). z La fonction thread dispose d'un et d'un seul argument totalement à la charge du programmeur. z La fonction thread retourne une valeur. z La fonction thread doit utiliser les paramètres et variables locaux aussi souvent que possible pour éviter les conflits avec la zone globale. z La mort du thread principal entraîne la mort de tous les threads.
  • 59. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 59 - Création de threads Unix Windows pthread_create ( ) pthread_exit ( ) pthread_join ( ) CreateThread ( ) ExitThread ( ) WaitForSingleObject ( )
  • 60. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 60 - Threads Unix
  • 61. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 61 - Unix: création d'un thread #include <pthread.h> int pthread_create ( pthread_t * thread, /* HANDLE */ pthread_attr_t *attr, void * (*start_routine)(void *), void * arg );
  • 62. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 62 - Exemple Thread Unix int main () { pthread_t a_thread ; void *thread_result ; if ( pthread_create (&a_thread,NULL,thread_function, (void *) message) < 0) { perror ("erreur creation du thread") ; exit (EXIT_FAILURE) ; } printf ("On attend la fin du threadn") ; if ( pthread_join (a_thread,&thread_result) < 0) { perror ("erreur join") ; exit (EXIT_FAILURE) ; } printf ("Fin du join, le thread a retourne %sn", (char *) thread_result) ; printf ("message contient maintenant : %sn",message) ; exit (EXIT_SUCCESS) ; } #include <stdio.h> #include <stdlib.h> #include <pthread.h> char message[] = "Bonjour" ; void *thread_function (void *arg) { printf ("thread demarre avec %sn", (char *) arg) ; sleep (3) ; strcpy (message,"Bye") ; pthread_exit ("au revoir") ; }
  • 63. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 63 - Threads Windows
  • 64. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 64 - Création thread Windows HANDLE CreateThread ( LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId );
  • 65. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 65 - Exemple thread Windows (1/2) #include <windows.h> #include <stdio.h> char message [ ] = "Bonjour" ; DWORD WINAPI thread_function (PVOID arg) { printf ("thread demarre avec %sn", (char *) arg) ; Sleep (3000) ; strcpy (message,"Bye") ; return 100 ; }
  • 66. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 66 - Exemple thread Windows (2/2) void main () { HANDLE a_thread ; DWORD a_threadId ; DWORD thread_result ; if ( (a_thread = CreateThread (NULL,0,thread_function,(PVOID)message,0,&a_threadId) ) == NULL) { perror ("erreur creation du thread") ; exit (EXIT_FAILURE) ; } printf ("On attend la fin du threadn") ; if ( WaitForSingleObject (a_thread,INFINITE) != WAIT_OBJECT_0) { perror ("erreur join") ; exit (EXIT_FAILURE) ; } GetExitCodeThread (a_thread,&thread_result) ; printf ("Fin du join, le thread a retourne %dn",thread_result) ; printf ("message contient maintenant : %sn",message) ; exit (EXIT_SUCCESS) ; }
  • 67. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 67 - Synchronisation des threads
  • 68. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 68 - Synchronisation threads z Tous les threads s'exécutent dans le même espace mémoire. z Deux threads peuvent vouloir accéder à la même zone mémoire "en même temps". z Sans précaution, le résultat sera imprévisible. z L'accès à des zones mémoires partagées doit donc être réglementé.
  • 69. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 69 - Un outil de synchronisation: le mutex z Un mutex est un sémaphore binaire pouvant prendre un état verrouillé ou déverrouillé. z Un mutex ne peut être partagé que par des threads d'un même processus. z Un mutex ne peut être verrouillé que par un seul thread à la fois. z Un thread qui tente de verrouiller un mutex déjà verrouillé est suspendu jusqu'à ce que le mutex soit déverrouillé.
  • 70. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 70 - Synchronisation Threads Unix
  • 71. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 71 - Exemple programme erroné int main () { int res1,res2 ; pthread_t a_thread1,a_thread2 ; void *thread_result1,*thread_result2 ; res1 = pthread_create (&a_thread1,NULL,function,NULL) ; res2 = pthread_create (&a_thread2,NULL,function,NULL) ; printf ("On attend la fin des threadsn") ; pthread_join (a_thread1,&thread_result1) ; pthread_join (a_thread2,&thread_result2) ; printf ("compteur = %dn",compteur) ; } #include <stdio.h> #include <pthread.h> int compteur = 0 ; void *function (void *arg) { int i,a ; for (i = 0 ; i < 10 ; i++) { a = compteur ; a = a + 1 ; sleep (1) ; compteur = a ; } }
  • 72. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 72 - Synchronisation des threads Unix z La synchronisation des threads peut se faire avec: • un sémaphore « Unix » (vu avec les processus). • Un sémaphore « Posix ». • un mutex.
  • 73. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 73 - Les sémaphores "Posix" z Unix gère les sémaphores à la norme "Posix" (proche de la définition des sémaphores de Djikstra). Sous Linux, ils ne sont utilisables que pour les threads (2ème argument de sem_init doit être 0). z Les types et prototypes nécessaires pour manipuler les sémaphores "Posix" sont dans le fichier d'entête "semaphore.h". z Un sémaphore est une variable de type sem_t.
  • 74. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 74 - Manipulation d'un sémaphore Posix z Initialisation: int sem_init(sem_t *sem, int pshared, unsigned int value); z Acquisition d'un accès: • bloquant: int sem_wait(sem_t * sem); • non bloquant: int sem_trywait(sem_t * sem); z Libération d'un accès: int sem_post(sem_t * sem); z Consultation de la valeur d'un sémaphore: int sem_getvalue(sem_t * sem, int * sval); z Destruction d'un sémaphore: int sem_destroy(sem_t * sem);
  • 75. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 75 - Exemple sémaphore Posix int main () { int res1,res2 ; pthread_t a_thread1,a_thread2 ; void *thread_result1,*thread_result2 ; sem_init (&sem,0,1) ; res1 = pthread_create (&a_thread1,NULL,function,NULL) ; res2 = pthread_create (&a_thread2,NULL,function,NULL) ; printf ("On attend la fin des threadsn") ; pthread_join (a_thread1,&thread_result1) ; pthread_join (a_thread2,&thread_result2) ; sem_destroy (&sem) ; printf ("compteur = %dn",compteur) ; } #include <stdio.h> #include <pthread.h> #include <semaphore.h> int compteur = 0 ; sem_t sem ; void *function (void *arg) { int i,a ; for (i = 0 ; i < 10 ; i++) { sem_wait (&sem) ; a = compteur ; a = a + 1 ; sleep (1) ; compteur = a ; sem_post (&sem) ; } }
  • 76. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 76 - Mutex sous Unix z Un mutex est une variable de type pthread_mutex_t z Elle peut être initialisée: • par la constante PTHREAD_MUTEX_INITIALIZER • Par un appel à la fonction: int pthread_mutex_init ( pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr ) ;
  • 77. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 77 - Utilisation mutex Unix z Verrouillage d'un mutex int pthread_mutex_lock (pthread_mutex_t *mutex); z Déverrouillage d'un mutex int pthread_mutex_unlock (pthread_mutex_t *mutex) ;
  • 78. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 78 - Exemple mutex Unix pthread_mutex_t monMutex = PTHREAD_MUTEX_INITIALIZER ; void *function (void *arg) { int i,a ; for (i = 0 ; i < 10 ; i++) { pthread_mutex_lock (&monMutex) ; a = compteur ; a = a + 1 ; sleep (1) ; compteur = a ; pthread_mutex_unlock (&monMutex) ; } }
  • 79. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 79 - Synchronisation Threads Windows
  • 80. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 80 - Synchronisation des threads Windows z La synchronisation des threads peut se faire avec: • un sémaphore (déjà vu avec les processus). • un mutex. • une section critique. • un verrou sur les variables.
  • 81. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 81 - Mutex Windows z Création d’un mutex: HANDLE CreateMutex ( LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, // Si TRUE, le mutex est créé et pris LPCTSTR lpName // Nom du mutex ); z Ouverture d’un mutex existant: HANDLE OpenMutex ( DWORD dwDesiredAccess, // MUTEX_ALL_ACCESS ou SYNCHRONIZE BOOL bInheritHandle, // Flag d’héritage LPCTSTR lpName // Nom du mutex );
  • 82. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 82 - Mutex Windows z Acquisition d’un mutex: DWORD WaitForSingleObject ( HANDLE hHandle, DWORD dwMilliseconds ); z Libération d’un mutex: BOOL ReleaseMutex (HANDLE hMutex);
  • 83. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 83 - Exemple Mutex 1/2 #include <stdio.h> #include <windows.h> int compteur = 0 ; DWORD WINAPI thread (LPVOID arg) { int i,a ; for (i = 0 ; i != 10 ; i++) { WaitForSingleObject ( (HANDLE) arg,INFINITE) ; a= compteur ; Sleep (1000) ; a = a + 1 ; compteur = a ; ReleaseMutex ( (HANDLE) arg) ; } return 0 ; }
  • 84. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 84 - Exemple mutex 2/2 void main () { DWORD ThreadId ; HANDLE ta,tb ; HANDLE mutex ; mutex = CreateMutex (NULL,FALSE,"MonMutex") ; ta = CreateThread (NULL,0,thread,mutex,0,&ThreadId) ; tb = CreateThread (NULL,0,thread,mutex,0,&ThreadId) ; WaitForSingleObject (ta,INFINITE) ; WaitForSingleObject (tb,INFINITE) ; printf ("compteur = %dn",compteur) ; }
  • 85. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 85 - Section critique z VOID InitializeCriticalSection ( LPCRITICAL_SECTION lpCriticalSection // Adresse de la section critique ); z VOID EnterCriticalSection ( LPCRITICAL_SECTION lpCriticalSection // Adresse de la section critique ); z VOID LeaveCriticalSection ( LPCRITICAL_SECTION lpCriticalSection // Adresse de la section critique ); z VOID DeleteCriticalSection ( LPCRITICAL_SECTION lpCriticalSection // Adresse de la section critique ); z BOOL TryEnterCriticalSection ( LPCRITICAL_SECTION lpCriticalSection // Adresse de la section critique );
  • 86. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 86 - Exemple de section critique #include <stdio.h> #include <windows.h> CRITICAL_SECTION verrou ; DWORD WINAPI function_thread (LPVOID param) { int i ; char *name = (char *) param ; EnterCriticalSection (&verrou) ; for (i = 0 ; i != 1000 ; i++) { printf ("%s: %dn",name,i) ; } LeaveCriticalSection (&verrou) ; return 0 ; }
  • 87. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 87 - Exemple de section critique (2/2) void main (int argc,char **argv []) { HANDLE ta,tb ; DWORD ThreadId ; InitializeCriticalSection (&verrou) ; ta = CreateThread (NULL,0,function_thread,"Thread A",0,&ThreadId) ; tb = CreateThread (NULL,0,function_thread,"Thread B",0,&ThreadId) ; Sleep (10000) ; }
  • 88. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 88 - Les fonctions "Interlocked" z LONG InterlockedIncrement( LPLONG lpAddend) ; // Pointeur sur la variable à incrémenter z LONG InterlockedDecrement( LPLONG lpAddend) ; // Pointeur sur la variable à décrémenter z PVOID InterlockedCompareExchange( PVOID *Destination, // pointer to the destination pointer PVOID Exchange, // the exchange value PVOID Comperand // the value to compare ); z LONG InterlockedExchange( LPLONG Target, // pointer to the 32-bit value to exchange LONG Value // new value for the LONG value pointed to by Target ); z LONG InterlockedExchangeAdd ( PLONG Addend, // pointer to the addend LONG Increment // increment value );
  • 89. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 89 - Programmation réseau
  • 90. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 90 - Modèle OSI
  • 91. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 91 - Communication dans le modèle OSI
  • 92. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 92 - L'implémentation IP
  • 93. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 93 - Architecture client/serveur z On construit, au-dessus des protocoles de transmission, des applications reposant sur un ou plusieurs serveurs et des clients. z Un serveur propose un ou plusieurs services (par exemple l'heure, le transfert de fichiers, etc.). z Un client utilise les services proposés. z Un client émet une requête dans un protocole donné (TCP/IP, UDP/IP) en précisant l'adresse de la machine et le service souhaité: le port de communication. z Le serveur est à l'écoute de ce port, détecte la requête et fournit la réponse à l'adresse et sur le port du client.
  • 94. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 94 - Architecture client/serveur serveur port 2143 client client requête réponse requête réponse
  • 95. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 95 - Allocation des ports z Un port est un entier sur 16 bits. z Les ports < 1024 sont privilégiés. z Certains ports sont alloués à des services reconnus; une liste peut être trouvée dans: • /etc/services sous Unix • C:WINNTsystem32driversetcservices sous Windows XP
  • 96. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 96 - Extrait du fichier "services" echo 7/tcp echo 7/udp discard 9/tcp sink null discard 9/udp sink null systat 11/tcp users #Utilisateurs actifs systat 11/tcp users #Utilisateurs actifs daytime 13/tcp daytime 13/udp chargen 19/tcp ttytst source #Generateur de caracteres chargen 19/udp ttytst source #Generateur de caracteres ftp-data 20/tcp #FTP donnees ftp 21/tcp #FTP controle ssh 22/tcp #SSH Remote Login telnet 23/tcp smtp 25/tcp mail #Format SMTP
  • 97. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 97 - Les sockets z Interface de programmation proposée par l'Unix de Berkeley et implémenté par WinSock de Trumpet pour Windows 3.x z Une socket peut être vue comme un point de communication entre processus. z Une socket peut être vue comme un triplé (protocole,adresse,port). z Les sockets permettent des échanges bidirectionnels entre processus. z Une socket est considérée comme un descripteur de fichiers par le système d'exploitation.
  • 98. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 98 - Processus/Socket processus socket
  • 99. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 99 - Les fonctions de programmation réseau z Fonctions sensiblement identiques sous Unix et Windows. z Sous Windows, l'utilisation d'une socket doit être précédée par un appel à la fonction: int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData ); Cela permet d'indiquer quelle version des sockets Windows (winsock) est nécessaire.
  • 100. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 100 - Exemple d'appel de WSAStartup WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { /* Probleme avec la DLL winsock */ return; } // Utilisation des sockets // … WSACleanup () ; // libération des zones mémoires allouées
  • 101. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 101 - La compatibilité winsock
  • 102. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 102 - Création d'une socket z Unix: #include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol); Retourne –1 en cas d'échec z Windows: #include <windows.h> SOCKET socket ( int af, int type, int protocol ); Retourne INVALID_SOCKET en cas d'échec
  • 103. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 103 - Arguments de la fonction socket IPPROTO_TCP, IPPROTO_UDP, IPPROTO_RAW En général, il y a un protocole par type et il n'est pas utile de le spécifier. S'il y en a plusieurs, on peut l'indiquer. protocol SOCK_STREAM Garantie l'intégrité de la transmission. SOCK_DGRAM Transmission sans connexion, sans garantie de datagrammes de longueur fixe. SOCK_RAW Transmissions internes aux système (nécessite un accès privilégié). … type PF_UNIX protocole local PF_INET protocole Internet PF_INET6 protocole Internet IPv6 … domain
  • 104. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 104 - Exemples de création de socket z Socket internet sans connexion (UDP/IP) socket (PF_INET,SOCK_DGRAM,IPPROTO_UDP) z Socket internet avec connexion (TCP/IP) socket (PF_INET,SOCK_STREAM,IPPROTO_TCP) z Socket de bas niveau: socket(PF_INET, SOCK_RAW, IPPROTO_RAW)
  • 105. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 105 - Communication en mode Internet non connecté Serveur Client Création socket UDP Documentation structure adresse (port d'écoute) Attachement socket/adresse Lecture / Écriture Création socket UDP Documentation structure adresse (IP,port) Écriture/Lecture
  • 106. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 106 - Structure d'adresse z On manipule des structures d'adresses dont le type générique est: struct sockaddr z Toutes les fonctions manipulant des adresses sont prototypées avec ce type. z En fonction du domaine, on utilisera des structures d'adresses particulières: z Dans le domaine Unix (PF_UNIX), on manipule des adresses de type struct sockaddr_un z Dans le domaine Internet (PF_INET), on manipule des adresses de type struct sockaddr_in
  • 107. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 107 - La structure struct sockaddr_in #include <netinet/in.h> struct sockaddr_in { short sin_family; /* AF_INET */ unsigned short sin_port; /* Port d'écoute ou de connexion */ struct in_addr sin_addr; /* INADDR_ANY ou IP de connexion */ char sin_zero[8]; /* Pas utilisé */ }; struct in_addr { u_long s_addr; };
  • 108. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 108 - Remplissage du champ sin_port z Attention à la représentation des entiers: utiliser la fonction htons () Exemple: struct sockaddr_in addr ; addr.sin_port = htons (2000) ; z Les fonctions de conversion unsigned long int htonl(unsigned long int hostlong); unsigned short int htons(unsigned short int hostshort); unsigned long int ntohl(unsigned long int netlong); unsigned short int ntohs(unsigned short int netshort);
  • 109. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 109 - Remplissage du champ sin_addr.addr z Méthode 1 addr.sin_addr.addr = inet_addr ("193.49.200.147") ; z Méthode 2 struct hostent { char *h_name; /* Nom officiel de la machine */ char **h_aliases; /* liste d'alias */ int h_addrtype; /* type d'adresse */ int h_length; /* longueur de l'addresse */ char **h_addr_list; /* liste d'adresses */ } struct hostent *host ; host = gethostbyname ("www.ensicaen.fr") ; memcpy ( &addr.sin_addr.s_addr,host->h_addr_list [0],host->length) ;
  • 110. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 110 - Attachement socket/adresse z Unix : int bind(int sockfd, struct sockaddr *my_addr, int addrlen); Retourne –1 en cas d'erreur, 0 sinon z Windows: int bind ( SOCKET s, const struct sockaddr FAR* name, int namelen ); Retourne SOCKET_ERROR en cas d'erreur, 0 sinon
  • 111. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 111 - Lecture d'une socket en mode non connecté z Unix : int recvfrom ( int s, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen); Retourne: Nombre d'octets lus ou –1 sinon z Windows: int recvfrom ( SOCKET s, char FAR* buf, int len, int flags, struct sockaddr FAR* from, int FAR* fromlen ) Retourne: Nombre d'octets lus ou 0 si la socket a été fermée ou SOCKET_ERROR
  • 112. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 112 - Écriture sur une socket en mode non connecté z Unix : int sendto ( int s, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen); Retourne le nombre de caractères écrits, -1 sinon z Windows: int sendto ( SOCKET s, const char FAR * buf, int len, int flags, const struct sockaddr FAR * to, int tolen ); Retourne le nombre de caractères écrits, SOCKET_ERROR sinon
  • 113. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 113 - Fermeture d'une socket z Unix : int close(int fd); Retourne 0 ou –1 en cas d'échec z Windows: int closesocket ( SOCKET s ); Retourne 0 ou SOCKET_ERROR en cas d'échec
  • 114. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 114 - Communication en mode Internet connecté Serveur Client Création socket d'écoute TCP Documentation structure adresse (port d'écoute) Documentation structure adresse (IP,port) Attachement socket/adresse Attente client Æ obtient une socket de service Création socket TCP Création d'un processus/thread Lecture/Écriture père: fermeture éventuelle socket de service fils: fermeture éventuelle socket d'écoute Connexion au serveur Lecture/Écriture Ouverture file d'attente
  • 115. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 115 - Ouverture de la file d'attente en mode connecté z Unix : int listen(int s, int backlog); Retourne 0 ou –1 en cas d'erreur z Windows: int listen ( SOCKET s, int backlog ); Retourne 0 ou SOCKET_ERROR en cas d'erreur
  • 116. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 116 - Attente d'une connexion cliente en mode connecté z Unix : int accept(int s, struct sockaddr *addr, int *addrlen); Retourne une socket de service ou –1 en cas d'erreur z Windows: SOCKET accept ( SOCKET s, struct sockaddr FAR* addr, int FAR* addrlen ); Retourne une socket de service ou INVALID_SOCKET en cas d'échec
  • 117. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 117 - Connexion à un serveur en mode connecté z Unix: int connect(int sockfd, struct sockaddr *serv_addr, int addrlen); Retourne 0 ou –1 en cas d'erreur z Windows: int connect ( SOCKET s, const struct sockaddr FAR* name, int namelen ); Retourne 0 ou SOCKET_ERROR en cas d'erreur
  • 118. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 118 - Lecture d'une socket en mode connecté z Unix: int recv(int s, void *buf, int len, unsigned int flags); Retourne le nombre d'octets lus ou –1 en cas d'erreur z Windows: int recv ( SOCKET s, char FAR* buf, int len, int flags ); Retourne le nombre d'octets lus ou SOCKET_ERROR en cas d'erreur
  • 119. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 119 - Écriture sur une socket en mode connecté z Unix: int send(int s, const void *msg, int len, unsigned int flags); Retourne le nombre d'octets écrits ou –1 en cas d'erreur z Windows: int send ( SOCKET s, const char FAR * buf, int len, int flags ); Retourne le nombre d'octets écrits ou SOCKET_ERROR en cas d'erreur
  • 120. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 120 - Fermeture d'une socket en mode connecté z La fonction close ( ) (Unix) ou closesocket ( ) (Windows) ferme la socket. z Toute écoute de cette socket par un hôte distant (recv ( ) ) retournera 0. z Tout envoi de données sur cette socket (send()) retournera –1. z En mode connecté, il est conseillé d'appeler préalablement la méthode shutdown ( ): • Unix: int shutdown(int s, int how); • Windows: int shutdown ( SOCKET s, int how ); le paramètre how peut contenir: - 0 (SD_RECEIVE) pour interdire la lecture sur cette socket. - 1 (SD_SEND) pour interdire l'envoi de données sur cette socket. - 2 (SD_BOTH) pour interdire les deux.
  • 121. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 121 - Manipulations simultanées de plusieurs sockets z Unix/Windows: int select ( int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); FD_CLR (int fd, fd_set *set); FD_ISSET (int fd, fd_set *set); FD_SET (int fd, fd_set *set); FD_ZERO (fd_set *set); - 1er argument de select ( ): majorant des descripteurs sous Unix, ignoré sous Windows - Valeur de retour de select ( ): . Nombre de sockets restant dans les ensembles . 0 si la sortie est due au time out . -1 (ou SOCKET_ERROR) en cas d'erreur
  • 122. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 122 - Options des sockets z Unix: int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); int setsockopt(int s, int level, int optname, const void*optval, socklen_t optlen); Retourne 0 ou –1 en cas d'erreur z Windows: int getsockopt ( SOCKET s, int level, int optname, char FAR* optval, int FAR* optlen ); int setsockopt ( SOCKET s, int level, int optname, const char FAR * optval, int optlen ); Retourne 0 ou SOCKET_ERROR en cas d'erreur
  • 123. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 123 - Paramètres des fonctions de gestion des options z s: Socket concernée par l'option z level: Niveau auquel s'applique l'option: SOL_SOCKET, IPPROTO_TCP, … z optname: Valeur de l'option en fonction du niveau choisi. z optval: Adresse d'une zone mémoire contenant la valeur de l'option. z optlen: Taille de la zone mémoire contenant la valeur de l'option.
  • 124. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 124 - Exemple 1: émission d'un datagramme UDP en broadcast #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> typedef int SOCKET ; #define SOCKET_ERROR -1 int main () { SOCKET s ; struct sockaddr_in addr,addr_exp ; int lg = sizeof (addr) ; int value = 1 ; /* Valeur de l'option brodcast */ char buffer [1024] ; /* Buffer de réception du datagramme */ s = socket (PF_INET,SOCK_DGRAM,IPPROTO_UDP) ; addr.sin_family = AF_INET ; addr.sin_port = htons (2000) ; addr.sin_addr.s_addr = inet_addr ("192.168.16.255") ; setsockopt (s,SOL_SOCKET,SO_BROADCAST,(char *)&value,sizeof (value)) ; strcpy (buffer,"test broadcast") ; sendto (s,buffer,strlen (buffer),0,&addr,lg) ; }
  • 125. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 125 - Exemple 2: envoi de paquets en multicast z Serveur: struct ip_mreq mreq; mreq.imr_multiaddr.s_addr=mcastAddr.s_addr; mreq.imr_interface.s_addr=htonl(INADDR_ANY); setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP, (void *) &mreq, sizeof(mreq)); z Client: unsigned char ttl = 1; setsockopt(sd,IPPROTO_IP,IP_MULTICAST_TTL, &ttl,sizeof(ttl))
  • 126. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 126 - Exemple 3: Réutilisation forcée d'un port TCP int sockdes ; int on = 1 ; sockdes=socket(AF_INET,SOCK_STREAM,0); setsockopt(sockdes,SOL_SOCKET,SO_REUSEADDR,(char *)&on,sizeof(on)) ;
  • 127. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 127 - Quelques fonctions utilitaires z Conversion d'une chaîne de caractère contenant une adresse IP en valeur 32 bits: unsigned int inet_addr (char *str) ; z Conversion d'une adresse IP 32 bits en chaîne de caractères: char *inet_ntoa (struct in_addr ip) ; z Obtention des informations sur l'association locale d'une socket: int getsockname(int s,struct sockaddr * name ,socklen_t * namelen ) z Obtention du nom de la machine locale dans name contenant au plus length caractères: int gethostname (char *name,int length) ;
  • 128. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 128 - Quelques fonctions utilitaires z Lecture non bloquante d'une socket: #include <fcntl.h> int optSock fcntl(sd, F_GETFL, &optSock); /* Lit options sur la socket */ optSock |= O_NDELAY; /* Définit options */ fcntl(sd, F_SETFL, &optSock); /* Applique options */
  • 129. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 129 - Remote Procedure Call
  • 130. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 130 - Généralités sur les RPC z Concepts introduit par SUN MicroSystem pour l'implémentation de la couche NFS (Network File System). z Objectif: une application cliente doit pouvoir exécuter une fonction sur une machine distante. z Le programmeur est déchargé de la gestion des sockets. z Ce concept d'informatique distribuée a servi de base à la gestion des RMI (Remote Method Invocation), EJB (Enterprise Java Bean) de Java et à CORBA (Common Object Request Broker Architecture).
  • 131. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 131 - Généralités sur les RPC
  • 132. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 132 - Vision des RPC par le programmeur
  • 133. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 133 - Vision des RPC par le concepteur
  • 134. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 134 - RPC: côté serveur z Les fonctions sont enregistrées auprès d'un processus portmap (TCP/111). z Une fonction est caractérisée par un entier long, un numéro de version et un nom. z Les entiers longs sont répertoriés ainsi (liste dans /etc/rpc sous Unix): Réservé 0x60000000 à 0xffffffff Réservé (Transient 0x40000000 à 0x5fffffff Non réservé 0x20000000 à 0x3fffffff Réservé (défini par Sun) 0x00000000 à 0x1fffffff Description Intervalle
  • 135. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 135 - Enregistrement des fonctions int registerrpc ( unsigned long prog, unsigned long vers, unsigned long proc, char *(*f) (), bool_t (*xdr_arg) (), bool_t (*xdr_res)() ) ;
  • 136. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 136 - Utilisation d'une fonction distante int callrpc ( char *machine, unsigned long prog, unsigned long vers, unsigned long proc, bool_t (*xdr_arg)(), char *arg, bool_t (*xdr_res)() char *res ) ;
  • 137. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 137 - XDR: Codage des types de données z Problème principal des rpc: trouver un codage commun de tous les types de données indépendant de la plate forme. z Une bibliothèque de codage a été créée: XDR (eXternal Data Representation). z Nécessite le fichier d'entête: #include <rpc/xdr.h> z Chaque type scalaire de base dispose d'une fonction de codage de la forme: bool_t xdr_<type> (XDR xdr, <type>argresp)
  • 138. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 138 - Codage XDR des types de base xdr_double double xdr_float float xdr_u_long unsigned long xdr_long long int xdr_u_short unsigned short xdr_short short int xdr_u_int unsigned int xdr_int int xdr_char char Fonction XDR associée TYPE C
  • 139. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 139 - Codage XDR d'une structure struct complexe { float reel,imaginaire ; } ; bool_t xdr_complexe (XDR *xdr,struct complexe *ptr) { return xdr_float (xdr,&ptr->reel) && xdr_float (xdr,&ptr->imaginaire) ; }
  • 140. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 140 - Exemple RPC: le fichier d'entête #include <rpc/types.h> #include <rpc/xdr.h> struct couple { float e1,e2 ; } ; int xdr_couple () ; struct couple *mult (struct couple *) ;
  • 141. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 141 - Exemple RPC: le serveur #include "exemple.h" main () { int rep ; rep = registerrpc (0x33333333,1,2,mult,xdr_couple,xdr_couple) ; if (rep < 0) { perror ("registerrpc") ; exit (1) ; } svc_run () ; }
  • 142. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 142 - Exemple RPC: le client #include <stdio.h> #include "exemple.h" int main (int argc,char **argv) { struct couple don,res ; if (argc != 2) { fprintf (stderr,"Usage: call machinen") ; exit (1) ; } for (;;) { printf ("Entrer 2 reels : ") ; scanf ("%f%f",&don.e1,&don.e2) ; if (callrpc (argv [1],0x33333333,1,2,xdr_couple,&don,xdr_couple,&res) == 0) { printf (" %f * %f = %fn",don.e1,don.e2,res.e1) ; printf (" %f / %f = %fn",don.e1,don.e2,res.e2) ; } else fprintf (stderr,"Erreurn") ; } }
  • 143. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 143 - Exemple RPC: la fonction mult () #include "exemple.h" char *mult (struct couple *p) { static struct couple res ; res.e1 = p->e1 * p->e2 ; res.e2 = p->e1 / p->e2 ; return ( (char *) &res) ; }
  • 144. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 144 - Exemple RPC: la conversion XDR #include "exemple.h" bool_t xdr_couple (XDR *xdrp,struct couple *p) { return ( xdr_float (xdrp,&p->e1) && xdr_float (xdrp,&p->e2) ) ; }
  • 145. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 145 - Le langage RPCL z Création d'un "Remote Procedure Call Language" (RPCL) pour simplifier l'écriture des fonctions XDR. z C'est un langage de description des types de données à utiliser. z La commande rpcgen va ensuite générer: • Toutes les fonctions xdr nécessaires. • Les squelettes (côté client et côté serveur) qui vont rendre transparent au programmeur l'aspect réseau et les conversions xdr.
  • 146. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 146 - Principe de fonctionnement es.x es.h es_clnt.c es_svc.c es_xdr.c rpcgen
  • 147. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 147 - Syntaxe RPCL z Le langage RPCL consiste en une série de définitions pouvant être de 6 types différents : • déclaration de constantes • déclaration de types énumérés • déclaration de structures (identique au C) • déclaration d'unions • déclaration de nouveaux types (typedef, identique au C) • déclaration de programme
  • 148. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 148 - Écriture du serveur z Les règles à observer pour l'écriture des fonctions du serveur sont les suivantes : • Les noms de fonctions (définies dans es.x) doivent être suivies du caractère "_" et du numéro de version; Si par exemple on a défini dans es.x une fonction gettime correspondant à la version 1, le nom de cette fonction dans le fichier proc.c sera gettime_1. • Les fonctions n'admettent qu'un seul paramètre qui est un pointeur sur le type déclaré dans le fichier es.x. • La valeur de retour des fonctions est également un pointeur sur le type déclaré dans le fichier es.x.
  • 149. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 149 - Écriture du client #include <rpc/rpc.h> #include "es.h" void main (int argc,char **argv) { CLIENT *cl ; /* server est une chaîne de caractère contenant le nom de la machine distante Le protocole est soit "udp", soit "tcp" */ cl = clnt_create (server,....PROG,.....VERS,protocole) ; if (cl == NULL) { clnt_pcreateerror (server) ; exit (1) ; } Appel de la fonction distante avec 2 paramètres : - adresse sur le type déclaré - variable cl }
  • 150. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 150 - Syntaxe RPCL Constantes const <identificateur> = <integer> ; Exemple : const MAX=8192 ; Types énumérés enum <identificateur> { enum-value-list } où enum-value-list représente : enum-value , enum-value-list où enum-value représente identificateur = valeur
  • 151. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 151 - Syntaxe RPCL: la clause program program <identificateur> { version <identificateur> { type nom_fonction (type) = <valeur> ; ... } = valeur ; } = valeur ; Exemple : program TIMEPROG { version TIMEVERS { unsigned int TIMEGET (void) = 1 ; void TIMESET (unsigned) = 2 ; } = 1 ; } = 0x2000000 ;
  • 152. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 152 - Exemple: le fichier RPCL: add.x struct data { unsigned int arg1; unsigned int arg2; }; typedef struct data data; struct reponse { unsigned int somme; int errno; }; typedef struct reponse reponse; program CALCUL { version VERSION_UN { void CALCUL_NULL(void) = 0; reponse CALCUL_ADDITION(data) = 1; } = 1; } = 0x20000001;
  • 153. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 153 - Génération des différents fichiers z La commande "rpcgen –a add.x" génère les fichiers: • add.h fichier d'entête à laisser inchangé • add_client.c programme client, à compléter • add_clnt.c squelette client à laisser inchangé • add_server.c fonctions distantes, à compléter • add_svc.c squelette serveur, à laisser inchangé • add_xdr.c codage xdr des types utilisés, à laisser inchangé
  • 154. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 154 - Exemple d'écriture d'une fonction reponse *calcul_addition_1(data *argp, struct svc_req * rqstp) { static reponse result; result.somme = argp->arg1 + argp->arg2 ; return (&result); }
  • 155. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 155 - Exemple: la fonction à enregistrer #include <stdio.h> char **essai_1 (char **chaine) { static char *buffer ; if (buffer == NULL) { buffer = calloc (10,sizeof (char)) ; } strncat (buffer,"Bonjourn",8) ; return &buffer ; }
  • 156. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 156 - Exemple: le client #include <rpc/rpc.h> #include "es.h" void main (int argc,char **argv) { CLIENT *cl ; char *buffer ; char **result ; buffer = (char *) calloc (20,sizeof (char)) ; cl = clnt_create ("e3000",MESSAGEPROG,MESSAGEVERS,"tcp") ; if (cl == NULL) { perror ("Connexion client") ; exit (1) ; } strncpy (buffer,"essai ",5) ; result = essai_1(&buffer) ; printf ("%sn",*result) ; }
  • 157. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 157 - La bibliothèque libsdl
  • 158. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 158 - Bibliothèque SDL z Tentative d'uniformiser les API Windows/Linux sur les thèmes: • audio • vidéo • threads • timers • … z Logiciels domaine public: http://www.libsdl.org
  • 159. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 159 - Exemple programmation thread int main (int argc,char **argv) { const int progeny = 5; SDL_Thread *kids[progeny]; int i, lots; lock = SDL_CreateMutex(); for ( i=0; i<progeny; ++i ) { kids[i] = SDL_CreateThread(thread_func, (void *)i); } SDL_Delay(5*1000); SDL_mutexP(lock); printf("On arrete les threadsn"); fin = 1; SDL_mutexV(lock); for ( i=0; i<progeny; ++i ) { SDL_WaitThread(kids[i], &lots); printf("Thread %d a utilise le mutex %d foisn", i, lots+1); } SDL_DestroyMutex(lock); return 0 ; } #include <stdio.h> #include "SDL.h" #include "SDL_thread.h" #include "SDL_mutex.h" int potty = 0; int fin; SDL_mutex *lock; int thread_func(void *data) { int num = (int) data; int compteur = 0; while ( fin == 0 ) { printf ("Thread %d, je prends le mutexn",num) ; SDL_mutexP(lock); printf ("Thread %d, j'ai pris le mutexn",num) ; SDL_Delay (1000) ; printf ("Thread %d, je rends le mutexn",num) ; SDL_mutexV(lock); compteur += 1 ; } printf("Fin Thread %dn",num); return(compteur); }
  • 160. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 160 - Exemple d'utilisation d'un mutex int main (int argc,char **argv) { const int progeny = 5; SDL_Thread *kids[progeny]; SDL_mutex *lock; int i, lots; lock = SDL_CreateMutex(); gotta_go = 1; for ( i=0; i<progeny; ++i ) { kids[i] = SDL_CreateThread(thread_func, lock); } SDL_Delay(5*1000); SDL_mutexP(lock); printf("Everybody done?n"); gotta_go = 0; SDL_mutexV(lock); for ( i=0; i<progeny; ++i ) { SDL_WaitThread(kids[i], &lots); printf("Thread %d used the potty %d timesn", i+1, lots); } SDL_DestroyMutex(lock); return 0 ; } #include <stdio.h> #include "SDL.h" #include "SDL_thread.h" #include "SDL_mutex.h" int potty = 0; int gotta_go; int thread_func(void *data) { SDL_mutex *lock = (SDL_mutex *)data; int times_went = 0 ; while ( gotta_go ) { SDL_mutexP(lock); ++potty; printf("Thread %d using the pottyn", SDL_ThreadID()); if ( potty > 1 ) { printf("potty already used!n"); } -- p otty; SDL_mutexV(lock); ++times_went; } printf("okn"); return(times_went); }
  • 161. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 161 - Programmation réseau IPv6
  • 162. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 162 - La programmation IPv6 z L'interface de programmation IPv6 est définie par les RFC 2553 et 2292. z Ce qui a changé: • Les structures d'adresse. • L'interface socket. • Les fonctions de conversions entre noms et adresses. • Les fonctions de conversion d'adresses.
  • 163. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 163 - Les structures d'adresses z Une nouvelle famille d'adresses AF_INET6 et une nouvelle famille de protocole PF_INET6 ont été définies dans <sys/socket.h>. z Pour des raisons de compatibilité, ces deux constantes sont égales: #define PF_INET6 AF_INET6 z Une adresse IPv6 est contenue dans la structure: struct in6_addr { uint8_t s6_addr[16]; /* IPv6 address */ };
  • 164. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 164 - Les structures d'adresses z La structure in6_addr peut également être définie par: struct in6_addr { union { uint8_t _S6_u8[16]; uint32_t _S6_u32[4]; uint64_t _S6_u64[2]; } _S6_un; }; #define s6_addr _S6_un._S6_u8
  • 165. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 165 - La structure sockaddr_in6 z Structure analogue à la structure sockaddr_in d'IPv4. z Il existe deux implémentations de cette structure: • Implémentation d'Unix 4.3BSD: struct sockaddr_in6 { sa_family_t sin6_family; /* AF_INET6 (champ sur 16 bits) */ in_port_t sin6_port; /* transport layer port # */ uint32_t sin6_flowinfo; /* IPv6 traffic class & flow info */ struct in6_addr sin6_addr; /* IPv6 address */ uint32_t sin6_scope_id; /* set of interfaces for a scope */ };
  • 166. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 166 - La structure sockaddr_in6 • Implémentation d'Unix 4.4BSD: struct sockaddr_in6 { uint8_t sin6_len; /* length of this struct */ sa_family_t sin6_family; /* AF_INET6 (champ sur 8 bits)*/ in_port_t sin6_port; /* transport layer port # */ uint32_t sin6_flowinfo; /* IPv6 flow information */ struct in6_addr sin6_addr; /* IPv6 address */ uint32_t sin6_scope_id; /* set of interfaces for a scope */ }; z Les systèmes qui implémentent la version 4.4BSD définissent une constante SIN6_LEN dans le fichier d'entête <netinet/in.h>.
  • 167. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 167 - L'adresse "wildcard" z En IPv4, la constante INADDR_ANY est utilisée par une application pour laisser au système le choix de l'adresse source. z En IPv6, il y a deux possibilités: • Utilisation d'une constante au moment de la déclaration: struct in6_addr anyaddr = IN6ADDR_ANY_INIT; • Utilisation d'une variable externe: extern const struct in6_addr in6addr_any; sin6.sin6_addr = in6addr_any;
  • 168. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 168 - L'adresse de "loopback" z En IPv4, l'adresse de "loopback" est définie par la constante INADDR_LOOPBACK. z En IPv6, il y a deux possibilités: • Utilisation d'une constante au moment de la déclaration: struct in6_addr loopbackaddr = IN6ADDR_LOOPBACK_INIT; • Utilisation d'une variable externe: extern const struct in6_addr in6addr_loopback; sin6.sin6_addr = in6addr_loopback;
  • 169. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 169 - L'interface socket z La fonction socket () utilise le même schéma qu'en IPv4: sock = socket (PF_INET6,SOCK_DGRAM,0) ; sock = socket (PF_INET6,SOCK_STREAM,0) ; z Les autres fonctions de l'interface socket sont inchangées, moyennant le transfert d'une adresse de type struct sockaddr_in6. z Principales fonctions inchangées: bind (), connect (), send (), sendto (), accept (), recv (), recvfrom (), getsockname (), getpeername ().
  • 170. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 170 - Les fonctions de conversion entre noms et adresses z Les fonctions gethostbyname (), gethostbyaddr (), getservbyname (), getservbyport () ont été remplacées par deux fonctions: getaddrinfo () et getnameinfo (): int getaddrinfo ( const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res); int getnameinfo ( const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags); z Les structures addrinfo sont allouées dynamiquement; il faut les désallouer après utilisation: void freeaddrinfo(struct addrinfo *ai);
  • 171. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 171 - La structure "addrinfo" struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ size_t ai_addrlen; /* length of ai_addr */ char *ai_canonname; /* canonical name for nodename */ struct sockaddr *ai_addr; /* binary address */ struct addrinfo *ai_next; /* next structure in linked list */ };
  • 172. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 172 - Les fonctions de conversion numériques d'adresses z Les deux fonctions inet_addr () et inet_ntoa () convertissent des adresses IPv4 entre une représentation binaire et une représentation textuelle. z Les fonctions équivalentes pour IPv6/IPv4 sont: int inet_pton(int af, const char *src, void *dst); const char *inet_ntop(int af, const void *src, char *dst, size_t size); z Ces fonctions ne sont pas supportées par winsock; on peut utiliser en remplacement WSAAddressToString() et WSAStringToAddress ().
  • 173. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 173 - Exemple de conversion d'adresse #include <stdio.h> #include <sys/socket.h> #include <netdb.h> int main (int argc,char **argv) { struct addrinfo hints ; struct addrinfo *res ; char str_addr [INET6_ADDRSTRLEN] ; memset (&hints,0,sizeof (struct addrinfo)) ; hints.ai_family = PF_INET6 ; if (getaddrinfo ("www.crihan.fr",NULL,&hints,&res) == 0) { struct in6_addr *src = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr ; if (inet_ntop (AF_INET6,src,str_addr,sizeof (str_addr)) != 0) { printf ("Adresse IPv6 = %sn",str_addr) ; } freeaddrinfo (res) ; } else printf ("Adresse non resoluen") ; } Résultat affiché: Adresse IPv6 = ::2001:660:7401:211:0:0
  • 174. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 174 - Même exemple sous Windows #include <stdio.h> #include <winsock2.h> #include <ws2tcpip.h> int main (int argc, char **argv []) { WSADATA wsadata ; if (WSAStartup (MAKEWORD (2,2),&wsadata) != 0) { fprintf (stderr,"Erreur dlln") ; return 1 ; } struct addrinfo hints ; struct addrinfo *res ; memset (&hints,0,sizeof (struct addrinfo)) ; hints.ai_family = PF_INET6 ; hints.ai_socktype = SOCK_STREAM ; if (getaddrinfo ("www.crihan.fr",NULL,&hints,&res) == 0) { char dest [INET6_ADDRSTRLEN] ; DWORD lg_dest = INET6_ADDRSTRLEN ; if (WSAAddressToString (res->ai_addr,res->ai_addrlen,NULL,dest,&lg_dest) == 0) { printf ("adresse IPv6 = %sn",dest) ; } freeaddrinfo (res) ; } WSACleanup () ; }
  • 175. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 175 - Annexes
  • 176. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 176 - Entête IP 32 bits Version IHL Type Service Longueur Totale Identification Flags Décalage Fragment TTL Protocole Contrôle entête Adresse Source Adresse Destination Options Remplissage
  • 177. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 177 - Entête TCP 32 bits Port source Port destination Numéro de séquence Numéro d'acquittement Long entête TCP U A P R S F R C S S Y I G K H T N N Taille de la fenêtre Total de contrôle Pointeur d'urgence Options (0, 1 ou plusieurs mots de 32 bits Données (optionnelles)
  • 178. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 178 - Entête UDP 32 bits Port source Port destination Longueur UDP Total de contrôle UDP
  • 179. - Ecole Nationale Supérieure d'Ingénieurs de Caen - © dp - 179 - Entête IPv6 Adresse source (16 octets) Adresse destination (16 octets) Ver sion Pri Etiquette de flot Longueur de charge utile En-tête suivant Nb max de sauts 32 bits