Vous êtes sur la page 1sur 117

K.

ElBedoui 1
Tube anonyme : pipe

Tube nommé : prise

Mémoire partagée

Files de messages

Sockets

Mme. K. ElBedoui 2
• Caractéristiques
– Fichier :
• temporaire
• pas d’entrée dans le système de fichier
• destruction automatique à la fin de l’utilisation
• pas d’utilisation de : open()/ lseek()
• Utilisable uniquement par le processus et sa descendance
– Taille : bornée = 4 Ko (PIPE_BUF)
– Communication :
• Sens : unidirectionnel
• mode : flot continu de caractères (streaming)
• ordre : FIFO
• via deux opérations :
– Lecture : read ( ), destructive
– Écriture : write ( ),
Mme. K. ElBedoui 3
P[1] P[0]
écriture lecture

Mme. K. ElBedoui 4
P[1] P[0]
écriture lecture

Processus 1

Intérêt :
Aucun

Mme. K. ElBedoui 5
P[1] P[0]
écriture lecture

Processus 1

Processus 2

Intérêt :
Communication : échange des informations

Mme. K. ElBedoui 6
P[1] P[0]
écriture lecture

Mme. K. ElBedoui 7
• Utilisation typique

P[1] P[0]
écriture lecture

Il faut faire la création du tube avant le fork()

Mme. K. ElBedoui 8
• Utilisation typique

P[1] P[0]
écriture lecture

Les descripteurs inutiles ?

Mme. K. ElBedoui 9
• Utilisation typique

P[1] P[0]
écriture lecture

Les descripteurs inutiles : il faut les fermer avec la primitive :


close ...
Mme. K. ElBedoui 10
• Écriture

P[1]
écriture

Primitive
ssize_t write (int fd, const void *buffer, size_t nbyte);

Mme. K. ElBedoui 11
• Écriture

P[1]
écriture

Primitive
ssize_t write (int fd, const void *buffer, size_t nbyte);

• Écriture atomique de la chaîne stockée dans buffer


• si nbyte inférieur à PIPE_BUF
• sinon découpage par le système en plusieurs écritures
• Bloquante
•tant qu’il n’y a pas de place pour écrire les nbyte caractères
Mme. K. ElBedoui •ou il n’existe pas de lecteurs (Signal SIGPIPE) 12
• Lecture

P[0]
lecture
Primitive
ssize_t read (int fd, void *buffer, size_t nbyte);

Mme. K. ElBedoui 13
• Lecture

P[0]
lecture
Primitive
ssize_t read (int fd, void *buffer, size_t nbyte);

• Lecture atomique d’au plus nbyte caractères


• Écriture de la chaîne lue à partir du pipe à l’adresse buffer
• Bloquante
• tant que le pipe est vide
Mme. K. ElBedoui • ou il n’existe pas d’écrivains (EOF) 14
• Code #include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{char buffer[30]; int fd[2];
pipe( fd );
switch (fork( ))
{
case -1 : perror ("fork( )"); exit (-1);
case 0 :
close (fd[1]);
printf ( "Fils : Lecture tube \n");
read (fd[0], buffer, sizeof (buffer));
printf ( "Fils : %s \n " , buffer);
break;
default :
close (fd [0]);
printf( "donner votre chaine de caractères" );
scanf (" %s", buffer);
printf ("Père : Écriture dans tube \n");
write (fd [1], buffer, 20);
wait (NULL);
break;
}
15
return (0);}
• Redirection
• Trois descripteurs standards :
Chaque processus a l’accès à trois descripteurs standard

1
stdout
0
stdin
2
stderr

Mme. K. ElBedoui 16
• Redirection
• Trois descripteurs standards :
Ces descripteurs sont :

1
stdout
0
stdin
2
stderr

Mme. K. ElBedoui 17
• Redirection
• Trois descripteurs standards :
En cas de communication entre deux processus

Mme. K. ElBedoui 18
• Redirection
• Trois descripteurs standards :
Les informations peuvent être transmises via un pipe

pipe

Mme. K. ElBedoui 19
• Redirection
• Trois descripteurs standards :
Dans ce dernier cas, des redirections doivent être établies

pipe

Connexion de la Connexion de
sortie standard de l’entrée standard de
processus 1 vers processus 2 depuis le
le tube tube

Mme. K. ElBedoui 20
• Redirection
• Trois descripteurs standards :
Ces redirections sont réalisées par la primitive dup2

pipe

dup2 (fd[1], stdout) dup2 (fd[0], stdin)

Mme. K. ElBedoui 21
• Redirection
• Motivation
• Affiner les résultats
• Utilité
$ commande1 | commande2

1. Création du tube par le shell


2. La commande1 écrit sur sa sortie standard que le shell redirige
vers le tube
3. La commande2 lit sur son entrée standard que le shell redirige
depuis le tube
4. Destruction du tube automatique, par le système à la fin de
l’exécution

Mme. K. ElBedoui 22
• Exécution d’une commande

Sh Sh Sh
fork wait
père père père

Sh
fils

exec
exit
« commande » stdout

Mme. K. ElBedoui 23
• Exécution de deux commandes

wait
wait

fd

exec exec
commande1 commande2

exit exit
Mme. K. ElBedoui 24
• Limites

• Les processus communicants doivent avoir un processus parent commun


(qui a créé le tube)

• Pas de rémanence du tube : détruit à la terminaison des processus

Mme. K. ElBedoui 25
• Caractéristiques
– Fichier :
• Il a une entrée dans le SGF
• Utilisable par tout processus connaissant son nom et ayant les droits
d’accès
– Communication :
• via deux opérations :
– Lecture : read ( ), destructive
– Écriture : write ( ),

Mme. K. ElBedoui 26
Mme. K. ElBedoui 27
Mme. K. ElBedoui 28
Mme. K. ElBedoui 29
Mme. K. ElBedoui 30
Mme. K. ElBedoui 31
Mme. K. ElBedoui 32
Mme. K. ElBedoui 33
!
Mme. K. ElBedoui 34
!

Mme. K. ElBedoui 35
fifo1

fifo2

Mme. K. ElBedoui 36
fifo1

fifo2

/* processus 1 */

int d_L1, d_E1;


...
d_E1=open("fifo1", O_WRONLY);
d_L1=open("fifo2", O_RDONLY);
Mme. K. ElBedoui 37
fifo1

fifo2

/* processus 1 */ /* processus 2 */

int d_L1, d_E1; int d_L2, d_E2;


... ...
d_E1=open("fifo1", O_WRONLY); d_E2=open("fifo2", O_WRONLY);
d_L1=open("fifo2", O_RDONLY); d_L2=open("fifo1", O_RDONLY);
Mme. K. ElBedoui 38
fifo1

fifo2

/* processus 1 */ /* processus 2 */

int d_L1, d_E1; int d_L2, d_E2;


... ...
d_E1=open("fifo1", O_WRONLY); interblocage d_E2=open("fifo2", O_WRONLY);
d_L1=open("fifo2", O_RDONLY); d_L2=open("fifo1", O_RDONLY);
Mme. K. ElBedoui 39
fifo1

fifo2

/* processus 1 */ /* processus 2 */

int d_L1, d_E1; int d_L2, d_E2;


... ...
d_E1=open("fifo1", O_WRONLY); d_L2=open("fifo1", O_RDONLY);
d_L1=open("fifo2", O_RDONLY); d_E2=open("fifo2", O_WRONLY);
Mme. K. ElBedoui 40
$ mkfifo Tube1
$ echo ”Bonjour ” > Tube1
$

$ cat <Tube1
Bonjour
$

Mme. K. ElBedoui 41
fifo1 (question)

SIGUSR1

fifo2 (réponse)

Mme. K. ElBedoui 42
fifo1 (question)

SIGUSR1

fifo2 (réponse)

Codes
Mme. K. ElBedoui 43
Mme. K. ElBedoui 44
Mme. K. ElBedoui 45
Mme. K. ElBedoui 46
Code

Données

•Les deux segments (Données et Piles) sont de


tailles variables

Pile

Mme. K. ElBedoui 47
Code

Données

•Adresses limites
•Pour éviter tout risque de chevauchement

Pile

Mme. K. ElBedoui 48
Nous pouvons étendre l’espace d’adressage d’un
processus via un segment de mémoire partagé

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

Mme. K. ElBedoui 49
RAM

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int shmid = shmget (key_t clé , /*clé du segment partagé */


size_t taille ,
int option );
Mme. K. ElBedoui 50
RAM

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int shmid = shmget (key_t clé , /*clé du segment partagé ~ IPC_PRIVATE*/


size_t taille ,
int option );
Mme. K. ElBedoui 51
RAM

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int shmid = shmget (key_t clé , /*clé du segment partagé ~ IPC_PRIVATE*/


size_t taille ,
•Eviter tout conflit
int option );
•Réservée au processus
Mme. K. ElBedoui appelant et à ses descendants 52
RAM

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int shmid = shmget (key_t clé , /*clé du segment partagé ~ IPC_PRIVATE*/


size_t taille , /*taille du segment en octet */
int option );
Mme. K. ElBedoui 53
RAM

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int shmid = shmget (key_t clé , /*clé du segment partagé ~ IPC_PRIVATE*/


size_t taille , /*taille du segment en octet */
int option ); /*option de création */
Mme. K. ElBedoui 54
RAM

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int shmid = shmget (key_t clé , /*clé du segment partagé ~ IPC_PRIVATE*/


size_t taille , /*taille du segment en octet */
Création si clé
int option ); /*IPC_CREAT
n’est pas déjà
Mme. K. ElBedoui
utilisée 55
RAM

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int shmid = shmget (key_t clé , /*clé du segment partagé ~ IPC_PRIVATE*/


size_t taille , /*taille du segment en octet */
Création de
int option ); /*IPC_EXCL*/
l’objet s’il
Mme. K. ElBedoui
n’existe pas 56
Void* shmat(int shmid, /*identificateur du segment partagé */
const void *adr,
int perm);
Mme. K. ElBedoui 57
Void* shmat(int shmid, /*identificateur du segment partagé */
const void *adr, /*adresse d’attachement dans le processus */
int perm);
Mme. K. ElBedoui 58
Void* shmat(int shmid, /*identificateur du segment partagé */
const void *adr, /*NULL*/
int perm); Le système doit
Mme. K. ElBedoui trouver la zone
59
Void* shmat(int shmid, /*identificateur du segment partagé */
const void *adr, /*adresse d’attachement dans le processus*/
int perm); /*droits d’accès : SHM_R, SHM_W, SHM_RND…*/
Mme. K. ElBedoui 60
Void* shmdt( const void *adr)

Mme. K. ElBedoui 61
Int shmctl ( shmid, IPC_RMID, buffer)

Mme. K. ElBedoui 62
Int shmctl ( shmid, IPC_STAT, buffer)

Mme. K. ElBedoui 63
struct shmid_ds {
struct ipc_perm shm_perm;
/* Propriétaire et permissions */
int shm_segsz;
/* Taille segment en octets */
time_t shm_atime;
/* Heure dernier attachement */
time_t shm_dtime;
/* Heure dernier détachement */
Time_t shm_ctime;
/* Heure dernier changement */
unsigned short shm_cpid;
Int shmctl ( shmid, IPC_STAT, buffer) /* PID du créateur */
unsigned short shm_lpid;
/* PID du dernier shmat( )/shmdt( ) */
short shm_nattch;
/* Nombre d’attachements */
};
Mme. K. ElBedoui 64
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

Mme. K. ElBedoui 65
typedef struct
#include <sys/types.h> {
#include <sys/ipc.h>
#include <sys/msg.h> int mtype;
char mtexte [256];
} message_t;

message_t message; mtype


mtexte
Mme. K. ElBedoui 66
*mtype *mtype *mtype
*m texte * mtexte *mtexte

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

Communication entre
un processus Emetteur et un processus Récepteur

Mme. K. ElBedoui 67
*mtype *mtype *mtype
*mtexte *mtexte * mtexte

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

Communication entre
un processus Emetteur et plusieurs processus Récepteurs

Mme. K. ElBedoui 68
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgid = msgget (key_t clé , /*clé de la file ~ IPC_PRIVATE*/


int option );

Mme. K. ElBedoui 69
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgid = msgget (key_t clé , /*clé de la file ~ IPC_PRIVATE*/


int option ); /*option de création ~ IPC-CREAT|IPC_EXCL|mode*/

Mme. K. ElBedoui 70
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgid = msgget (key_t clé , /*clé de la file ~ IPC_PRIVATE*/


int option ); /*option de création ~ IPC-CREAT|IPC_EXCL|0666*/

Mme. K. ElBedoui 71
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgid = msgget (key_t clé , /*clé de la file ~ IPC_PRIVATE*/


int option ); /*option de création ~ IPC-CREAT|IPC_EXCL|0666*/

Par défaut :
Mme. K. ElBedoui 72
000 -> pb
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd ( int msgid , /*identificateur de la file*/


const void * message,
int taille ,
int option );
Mme. K. ElBedoui 73
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd ( int msgid , /*identificateur de la file*/


const void * message, /*la zone mémoire où récupérer le message*/
int taille ,
int option );
Mme. K. ElBedoui 74
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd ( int msgid , /*identificateur de la file*/


const void * message, /*la zone mémoire où récupérer le message*/
int taille , /*la taille du texte à envoyer (mtexte)*/
int option );
Mme. K. ElBedoui 75
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd ( int msgid , /*identificateur de la file*/


const void * message, /*la zone mémoire où récupérer le message*/
int taille , /*la taille du texte à envoyer (mtexte)*/
int option ); /*option d’envoi */
Mme. K. ElBedoui 76
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd ( int msgid , /*identificateur de la file*/


const void * message, /*la zone mémoire où récupérer le message*/
int taille , /*la taille du texte à envoyer (mtexte)*/
int option ); /*option d’envoi ~IPC_NOWAIT*/
Mme. K. ElBedoui 77
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd ( int msgid , /*identificateur de la file*/


const void * message, /*la zone mémoire où récupérer le message*/
int taille , /*la taille du texte à envoyer (mtexte)*/
int option ); /*option d’envoi ~IPC_NOWAIT*/
Mme. K. ElBedoui
Non bloquant 78
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv ( int msgid , /*identificateur de la file*/
const void * message,
int taille ,
int type,
int option );
Mme. K. ElBedoui 79
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv ( int msgid , /*identificateur de la file*/
const void * message, /*la zone mémoire où sauvegarder le message*/
int taille ,
int type,
int option );
Mme. K. ElBedoui 80
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv ( int msgid , /*identificateur de la file*/
const void * message, /*la zone mémoire où sauvegarder le message*/
int taille , /*la taille max du texte à récupérer(mtexte)*/
int type,
int option );
Mme. K. ElBedoui 81
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv ( int msgid , /*identificateur de la file*/
const void * message, /*la zone mémoire où sauvegarder le message*/
int taille , /*la taille max du texte à récupérer(mtexte)*/
int type, /* le type de message à récupérer (mtype)
int option );
Mme. K. ElBedoui 82
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv ( int msgid , /*identificateur de la file*/
const void * message, /*la zone mémoire où sauvegarder le message*/
int taille , /*la taille max du texte à récupérer(mtexte)*/
int type, /* le type de message à récupérer (mtype)
int option );
Mme. K. ElBedoui 83
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv ( int msgid , /*identificateur de la file*/
const void * message, /*la zone mémoire où sauvegarder le message*/
int taille , /*la taille max du texte à récupérer(mtexte)*/
int type, /* le type de message à récupérer (mtype)
int option );
=0
Mme. K. ElBedoui
Le 1er message est extrait  son type
84
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv ( int msgid , /*identificateur de la file*/
const void * message, /*la zone mémoire où sauvegarder le message*/
int taille , /*la taille max du texte à récupérer(mtexte)*/
int type, /* le type de message à récupérer (mtype)
int option );
>0
Mme. K. ElBedoui
Le 1er message de type désigné est extrait
85
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv ( int msgid , /*identificateur de la file*/
const void * message, /*la zone mémoire où sauvegarder le message*/
int taille , /*la taille max du texte à récupérer(mtexte)*/
int type /* le type de message à récupérer (mtype)
int option ); <0
Mme. K. ElBedoui Le 1er message de type > |type désigné|
86
est extrait
msgctl (msgid , IPC_RMID, buffer);

Mme. K. ElBedoui 87
struct msqid_ds {
struct ipc_perm msg_perm;
/* Propriétaire et permissions */
time_t msg_stime;
/* Heure du dernier msgsnd( ) */
time_t msg_rtime;
/* Heure du dernier msgrcv( ) */
time_t msg_ctime;
/* Heure de la dernière modification */
unsigned long __msg_cbytes;
/* Nombre actuel d’octets dans la file (non standard) */
msgqnum_t msg_qnum;
msgctl (msgid , IPC_STAT, buffer);
/* Nombre actuel de messages dans la file */
msglen_t msg_qbytes;
/* Nombre maximal d’octets autorisés dans la file */
pid_t msg_lspid;
/* PID du dernier msgsnd( ) */
pid_t msg_lrpid;
/* PID du dernier msgrcv( ) */
};
Mme. K. ElBedoui 88
pipe msg

Tubes IPC
shm
prise

Processus 1 Processus 2

Noyau

Communication entre
processus locaux
Mme. K. ElBedoui 89
Processus 1 Processus 2
Socket

Noyau Noyau

Communication entre
processus distants
Mme. K. ElBedoui 90
Une socket :

❑ est un point de communication


❑ permet à un processus d’échanger l’information avec un autre processus
❑ utilise le réseau et un protocole donné

Processus 1 Processus 2
Socket

Noyau Noyau

Mme. K. ElBedoui 91
Utilisation typique :

Dans le cas d’une communication client/serveur :

Le client émet une requête vers le serveur accessible via son adresse
et le numéro de port qui désigne un service particulier du serveur

Le serveur reçoit la demande et répond au client en connaissant son


adresse de machine et son numéro de port.

Mme. K. ElBedoui 92
Utilisation typique :

L’échange de messages entre les 2 machines client et serveur suit alors le


scénario suivant :

1- chaque machine crée une socket,


2- chaque socket sera associée à un port de la machine hôte,
3- les deux sockets seront explicitement connectées si on utilise un
protocole en mode connecté,
4- chaque machine lit et/ou écrit dans sa socket,
5- les données vont d’une socket à une autre à travers le
réseau,
6- une fois terminé chaque machine ferme sa socket.

Mme. K. ElBedoui 93
Qu’est-ce qu’une adresse ?

❖ Une adresse identifie la socket de manière unique au sein d’un domaine.


❖ L’adresse est choisie par le processus détenteur de la socket : attachement
d’une socket à une adresse.

➢ pas de communication entre des sockets de domaines différents

Exemples :

❖ Domaine UNIX (local) : référence (comme les autres fichiers)


❖ Domaine Internet : une adresse IP et un port.

Démos sockunix et netstat -a -f domaine

Mme. K. ElBedoui 94
#include <sys/types.h>
#include <sys/socket.h>

int sid = socket (int domaine, int type , int protocole);

Mme. K. ElBedoui 95
#include <sys/types.h>
#include <sys/socket.h>

int sid = socket (int domaine, int type , int protocole);

• AF_UNIX pour un domaine local Unix

• AF_INET pour un domaine internet

• Autres domaines : AF_ISO, AF_NS,AF_IMPLINK, AF_X25

Mme. K. ElBedoui 96
#include <sys/types.h>
#include <sys/socket.h>

int sid = socket (int domaine, int type , int protocole);

• SOCK_DGRAM Transmission de datagrammes en mode non connecté, aucune garantie


de fiabilité

• SOCK_STREAM transmission flux de données en mode connecté et fiabilité maximale

• Autres types : SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET

Mme. K. ElBedoui 97
#include <sys/types.h>
#include <sys/socket.h>

int sid = socket (int domaine, int type , int protocole);

• IPPROTO_IP par défaut le système choisit le protocole =0

• IPPROTO_UDP pour le protocole UDP (socket de type SOCK_DGRAM) = 17

• IPPROTO_TCP pour le protocole TCP (socket de type SOCK_STREAM) = 6

• Autres protocoles

• dans le domaine AF_UNIX, il n ’y a pas de protocole


Mme. K. ElBedoui 98
#include <sys/types.h>
#include <sys/socket.h>

int bind ( sid , adrServ, taille);

• sid l’identifiant de la socket =valeur retournée par la primitive socket()

• adrSev structure définissant l’adresse et le numéro de port côté serveur

• taille la longueur en octets de l’adresse adrServ

Mme. K. ElBedoui 99
#include <sys/types.h>
#include <sys/socket.h>

int connect ( sid , adrServ, taille);

• sid l’identifiant de la socket =valeur retournée par la primitive socket()

• adrServ structure définissant l’adresse et le numéro de port côté client

•taille la longueur en octets de l’adresse adrServ

Mme. K. ElBedoui 100


#include <sys/types.h>
#include <sys/socket.h>

int listen ( sid , nbConnexion);

• sid l’identifiant de la socket =valeur retournée par la primitive socket()

• nbConnexion longueur maximale de la file d’attente

Mme. K. ElBedoui 101


#include <sys/types.h>
#include <sys/socket.h>

int ser = accept ( sid , adrClt, taille);

• sid l’identifiant de la socket =valeur retournée par la primitive socket()

• adrClt structure définissant l’adresse et le numéro de port côté client

•taille la longueur en octets de l’adresse adrClt

•ser résultat de accept() qui est un descripteur

Mme. K. ElBedoui 102


Client Serveur

socket()
socket()
bind()

connect()
listen()

Connexion
accept()

send()
recv()
Données
send()
recv()
103
Mme. K. ElBedoui
close() close()
Client Serveur

socket()
socket()
bind()

sendto()
recvfrom()

recvfrom() sendto()

close() close()
Mme. K. ElBedoui 104
Mécanismes

Mme. K. ElBedoui 105


Mécanismes
• bind permet de donner à la socket serveur une adresse IP et un numéro
de port.

Mme. K. ElBedoui 106


La structure hostent

Mme. K. ElBedoui 107


• Port : dans lequel un processus
dépose et récupère ses données
(expédition et émission)

• Chaque processus a un n° de port :


identité logique

Mme. K. ElBedoui 108


Trois catégories de port :

❖ Ports well-known : de 0 à 1023


Sur la plupart des systèmes, ne peuvent être utilisés que par des processus
système (ou root) ou des programmes exécutés par des utilisateurs privilégiés

❖ Ports registered : de 1024 à 49 151


Sur la plupart des systèmes, peuvent être utilisés par des processus utilisateur
ordinaires ou des programmes exécutés par des utilisateurs ordinaires

❖ Ports dynamic/private : de 49 152 à 65 535


Alloués dynamiquement
/etc/services
Mme. K. ElBedoui 109
Récupération des caractéristiques d’une machine distante à partir de son
nom :
#include <netdb.h>
struct hostent *gethostbyname( const char *nomMachine);
/* renvoie NULL si erreur */
struct hostent
{
char *h_name; /* nom officiel de la machine */
char **h_aliases; /* liste d’alias */
int h_addrtype; /* type d’adresse (AF_INET) */
int h_length; /* longueur de l’adresse */
char **h_addr_list; /* liste des adresses, ordre du réseau */
#define h_addr h_addr_list[0] /* premiere adresse */
};
Mme. K. ElBedoui 110
Création d’une socket :

#include <sys/types.h>
#include <sys/socket.h> /* socket(), bind() ... */

int socket
(
int domaine, /* AF_UNIX | AF_INET */
int type, /* SOCK_DGRAM | SOCK_STREAM */
int protocole /* 0 : protocole par défaut */
);

Supprimer une socket :


close(int sock).
Mme. K. ElBedoui 111
/* Adresse internet d’une machine */
struct in_addr { u_long s_addr; /* codee en binaire */ }

/* Adresse internet d’une socket */


struct sockaddr_in {
sa_family_t sin_family; /* AF_INET */
in_port_t sin_port; /* numero du port associe */
struct in_addr sin_addr; /* adresse internet de la machine */
char sin_zero[8]; /*un champ de 8 caractères nuls */
};

Si sin_addr.s_addr a comme valeur INADDR_ANY, la socket est associée à


toutes les adresses de la machine (si celle-ci en possède plusieurs). Pour les
machines possédant une seule adresse, la socket est associée à celle-ci (ce
qui évite l’appel à la fonction gethostname()).
Mme. K. ElBedoui 112
Convertir l’adresse Internet de l’hôte in en une chaîne de caractères dans la
notation avec nombres et points :

# include <arpa/inet.h>
char * inet_ntoa (struct in_addr in);

La chaîne est renvoyée dans un buffer alloué statiquement, qui est donc
écrasé à chaque appel.

Mme. K. ElBedoui 113


Conversion d’ordre des octets entre un hôte et un réseau

Sur les architectures i386, l’ordre des octets est différent de celui des réseaux
comme Internet : l’octet de poids faible est placé en premier (on parle de LSB
pour Least Significant Byte first), alors que sur les réseaux, c’est l’octet de
poids fort en premier (on parle de MSB pour Most Significant Byte first).
Il est donc nécessaire d’utiliser les fonctions suivantes pour effectuer
correctement la conversion lors de la spécification des numéros de ports :

#include <netinet/in.h>

uint32_t htonl (uint32_t entierlong); /* hôte -> réseau */


uint16_t htons (uint16_t entiercourt); /* hôte -> réseau */
uint32_t ntohl (uint32_t netlong); /* réseau -> hôte */
uint16_t ntohs (uint16_t netshort); /* réseau -> hôte */
Mme. K. ElBedoui 114
Les bibliothèques

#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <string.h> /* memcpy(), strcmp() */
#include <unistd.h>
#include <netdb.h> /* gethostbyname() */
#include <sys/types.h>
#include <sys/socket.h> /* socket(), connect(), bind(), ... */
#include <netinet/in.h> /* pour les sokets AF_INET, htonl(), etc. */
#include <arpa/inet.h> /* inet_ntoa() */

Mme. K. ElBedoui 115


int main ( int argc, char* argv[])
{ int socketfd, portno, n; Client.c
struct sockaddr_in serv_addr;
struct hostent *serv;
char buffer[256];
if (argc<3) {fprintf(stderr,"specifier les arguments de %s \n ", argv[0]);exit(-1);}
portno=atoi(argv[2]);
socketfd=socket(AF_INET, SOCK_STREAM,0);
if (socketfd <0) { printf ("erreur de creation"); exit(-1);}
server =gethostbyname(argv[1]);
if (server==NULL) {printf ("erreur de nom serveur"); exit(-1);}
bzero ((char*)&serv_addr,sizeof(serv_addr));
serv_addr.sin_family= AF_INET;
serv_addr.sin_port=htons(portno);
memcpy (&serv_addr.sin_addr, server->h_addr,server->h_length);
if(connect(socketfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))<0) {printf ("erreur de connection\n"); exit(-1);}
bzero (buffer,256);
printf ("\nDonner la chaine svp : \n");
fgets(buffer,255,stdin);
n=write(socketfd, buffer, strlen(buffer));
if (n<0) {printf ("erreur de ecriture\n"); exit(-1);}
bzero(buffer,256);
n=read(socketfd, buffer, 255);
if (n<0) {printf ("erreur de lecture\n"); exit(-1);}
printf("\n La reponse du serveur est : %s \n", buffer);
Mme. K. ElBedoui 116
return 0; }
int main ( int argc, char* argv[])
{ int socketfd, newsocketfd, portno, clilen, n; Serveur.c
struct sockaddr_in serv_addr, cli_addr;
char buffer[256];
if (argc<2) {fprintf(stderr,"specifier le port ");exit(-1);}
portno=atoi(argv[1]);
socketfd=socket(AF_INET, SOCK_STREAM,0);
if (socketfd <0) { printf ("erreur de creation"); exit(-1);}
bzero ((char*)&serv_addr,sizeof(serv_addr));
serv_addr.sin_family= AF_INET;
serv_addr.sin_addr.s_addr= htonl(INADDR_ANY);
serv_addr.sin_port=htons(portno);
if(bind(socketfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))<0) {printf ("erreur de bind\n"); exit(-1);}
listen(socketfd,5);
clilen=sizeof(cli_addr);
newsocketfd=accept(socketfd, (struct sockaddr *) & cli_addr, &clilen);
if (newsocketfd <0) { printf ("erreur de acceptation\n"); exit(-1);}
bzero (buffer,256);
n=read(newsocketfd, buffer, 255);
if (n<0) {printf ("erreur de ecriture\n"); exit(-1);}
printf("\nvoici le message reçu :%s\n", buffer);
bzero(buffer,256);
n=write(newsocketfd, "SERVEUR : jai bien reçu la requete", 40);
if (n<0) {printf ("erreur de lecture\n"); exit(0);}
return
Mme. K.0;ElBedoui 117
}

Vous aimerez peut-être aussi