0% ont trouvé ce document utile (0 vote)
475 vues7 pages

Sockets Datagramme en C

Ce document décrit les principes de base de la communication par sockets datagramme. Il présente les cinq primitives fondamentales pour créer une socket, l'attacher à une adresse, recevoir et envoyer des informations, et fermer la socket. Des explications détaillées sont fournies sur la structure des adresses de sockets et les fonctions de conversion entre formats hôte et réseau.

Transféré par

Abdo Elmamoun
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
475 vues7 pages

Sockets Datagramme en C

Ce document décrit les principes de base de la communication par sockets datagramme. Il présente les cinq primitives fondamentales pour créer une socket, l'attacher à une adresse, recevoir et envoyer des informations, et fermer la socket. Des explications détaillées sont fournies sur la structure des adresses de sockets et les fonctions de conversion entre formats hôte et réseau.

Transféré par

Abdo Elmamoun
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

DUT Informatique

iUT ORSAY
Département Informatique
Module Système S4 C
2009 / 2010

Travaux Dirigés no 2 : Sockets Datagramme

Objectifs : comprendre les principes et les mécanismes de communication par


sockets datagramme, être capable de réaliser des systèmes client-serveur sur
ce mode de communication.

1 Notes de cours
Les sockets sont des interfaces de communication bidirectionnelles entre différents processus,
qu’ils appartiennent à un même système ou non. Dans le cas des sockets datagramme, cette
interface s’apparente à une boîte aux lettres : on envoie des messages complets à n’importe qui
pourvu qu’on en connaisse l’adresse. On est assuré de la bonne réception du message seulement
si le destinataire la confirme. L’algorithme général de communication par sockets datagramme
est le suivant :
1. Créer une socket (primitive socket)
2. Attacher la socket à une adresse (primitive bind)
3. Communiquer (tant qu’on veut) :
- Recevoir (primitive recvfrom), ou
- Émettre (primitive sendto)
4. Terminer (primitive close)

Il y a donc simplement 5 primitives fondamentales pour communiquer avec les sockets data-
grammes. Elles sont hélas compliquées par la nécessité de connaître d’autres fonctions utili-
taires et la structure de données de l’adresse d’une socket.

1.1 Création d’une socket


# i n c l u d e < s y s / s o c k e t . h>
int socket (
i n t domaine , / ∗ AF_UNIX , AF_INET ∗ /
i n t type , / ∗ SOCK_DGRAM, SOCK_STREAM ∗ /
int protocole / ∗ 0 : p r o t o c o l e par d e f a u t ∗ /
);

La primitive socket demande au système la création d’une socket et renvoie son descripteur
en cas de succès ou -1 en cas d’echec. Le domaine définit l’ensemble de sockets avec les-
quelles une communication pourra être établie : AF_UNIX pour le domaine Unix, AF_INET pour
Internet, on utilisera toujours ce dernier. Le type définit le type de socket : datagramme avec
SOCK_DGRAM et stream avec SOCK_STREAM.
Travaux Dirigés no 2 Sockets Datagramme 2/7

1.2 Attachement d’une socket à une adresse


# i n c l u d e < s y s / s o c k e t . h>
i n t bind (
int descripteur , / ∗ D e s c r i p t e u r de l a s o c k e t ∗ /
struct sockaddr ∗ adresse , /∗ Poiteur vers l ’ adresse d ’ attachement ∗/
int longueur_adresse / ∗ L o n g u e u r de l ’ a d r e s s e en o c t e t s ∗ /
);

La primitive bind effectue l’attachement à l’adresse pointée par adresse de la socket de des-
cripteur descripteur et la rend ainsi accessible depuis des processus ne connaissant pas le
descripteur (mais l’adresse !). Elle retourne 0 en cas de succès ou -1 en cas d’echec. Dans le
cas du domaine AF_INET, cette adresse a la forme suivante :

# i n c l u d e < n e t i n e t / i n . h>
struct in_addr { / ∗ A d r e s s e i n t e r n e t d ’ une m a c h i n e ∗ /
u_long s_addr ; / ∗ − I c i pour r a i s o n s h i s t o r i q u e s ∗ /
};
struct sockaddr_in{ /∗ A d r e s s e i n t e r n e t d ’ une s o c k e t ∗ /
short sin_family ; /∗ − AF_INET ∗ /
u_short sin_port ; /∗ − Numero de p o r t a s s o c i e ∗ /
struct in_addr sin_addr ; /∗ − V o i r c i −d e s s u s ∗ /
char s i n _ z e r o [ 8 ] ; /∗ − Un champ de 8 c a r a c t e r e s n u l s ∗ /
};

Certaines valeurs «joker» sont possibles : INADDR_ANY pour sinaddr.s_addr attache la so-
cket à toutes les adresses possibles de la machine. 0 pour sin_port laisse le système décider
du numéro de port (pour un client d’une application client-serveur il n’a par exemple aucun
intérêt).

Une nouvelle difficulté à relever est la traduction des informations du système hôte (host) vers
des données dans le format du réseau (network) pour remplir les structures de données ci-
dessus. En effet puisque les sockets sont indépendantes du système, des représentations très
différentes peuvent être utilisées entre deux processus cherchant à communiquer (nombre de
bits différent, bit de poids fort à un endroit différent, complément à un ou zéro...). Pour cela
existent quatre primitives de traduction, (1) ntohs : network to host short, (2) ntohl : net-
work to host long, (3) htons : host to network short, (4) htonl : host to network long. Ainsi
connaissant le numéro de port, port, et ayant auparavant préparé une structure adresse de
type struct sockaddr_in, nous pourrions la remplir de la manière suivante :

# i n c l u d e < a r p a / i n e t . h> / ∗ Pour h t o n l ( ) , h t o n s ( ) ou i n e t _ a d d r ( ) ∗ /


...
memset ( ( char ∗ ) a d r e s s e , ’ 0 ’ , s i z e o f ( s t r u c t s o c k a d d r _ i n ) ) ; / ∗ T o u t a z e r o . ∗ /
a d r e s s e . s i n _ f a m i l y = AF_INET ;
a d r e s s e . s i n _ a d d r . s _ a d d r = h t o n l (INADDR_ANY ) ;
adresse . s in _ p o r t = htons ( port ) ;
...

Si on ne choisit pas INADDR_ANY, le champ adresse.sin_addr.s_addr doit contenir l’adresse


IP de la machine sous forme entière, par exemple si l’adresse est 130.57.12.30, on utilisera la
valeur htonl(130.224 + 57.216 + 12.28 + 30). Plus simplement, on peut aussi utiliser la chaîne
de caractères de l’adresse IP de la manière suivante : inet_addr("130.57.12.30"). Si on ne
connaît que le nom de la machine, on peut utiliser la série d’instructions suivante :

IUT d’Orsay – DUT Informatique 2009 / 2010 Module Système S4 C


Travaux Dirigés no 2 Sockets Datagramme 3/7

# i n c l u d e < n e t d b . h> / ∗ Pour h o s t e n t e t g e t h o s t b y n a m e ( ) ∗ /


...
struct hostent ∗ host ;
h o s t = g e t h o s t b y n a m e ( " nom_machine . i u t −o r s a y . f r " ) ;
memcpy ( ( v o i d ∗)& a d r e s s e . s i n _ a d d r , ( v o i d ∗ ) h o s t −>h _ a d d r , h o s t −> h _ l e n g t h ) ;
a d r e s s e . s i n _ f a m i l y = h o s t −> h _ a d d r t y p e ;
...

1.3 Réception d’information


# i n c l u d e < s y s / s o c k e t . h>
i n t recvfrom (
int descripteur , /∗ D e s c r i p t e u r de l a s o c k e t ∗ /
v o i d ∗ message , /∗ A d r e s s e de r e c e p t i o n ∗ /
i n t longueur , /∗ L o n g u e u r max du m e s s a g e ∗ /
int option , /∗ 0 ∗/
struct sockaddr ∗ adresse , /∗ P o i n t e u r s u r a d r e s s e de l ’ e m e t t e u r ∗ /
int ∗ longueur_adresse /∗ Pointeur sur longueur adresse emetteur ∗/
);

La primitive recvfrom permet de recevoir de l’information depuis une socket et de la placer


à l’adresse indiquée par message. Le paramètre longueur donne la taille de la zone allouée
pour le message en octets, si le message reçu est trop grand, le surplus sera perdu. Au moment
de l’appel, le champ longueur_adresse est une donnée indiquant la taille de l’espace alloué à
l’adresse adresse, il faut donc l’initialiser (typiquement à sizeof(struct sockaddr)). Au
retour de cette fonction, les champs adresse et longueur_adresse permettront de connaître
les coordonnées de l’émetteur. Cette primitive est bloquante (le processus est bloqué jusquà
réception d’un message), elle retourne le nombre de caractères lus en cas de succès, -1 en cas
d’échec.

1.4 Envoi d’information


# i n c l u d e < s y s / s o c k e t . h>
int sendto (
int descripteur , /∗ D e s c r i p t e u r de l a s o c k e t ∗ /
v o i d ∗ message , /∗ A d r e s s e du m e s s a g e a e n v o y e r ∗ /
i n t longueur , /∗ L o n g u e u r du m e s s a g e ∗ /
int option , /∗ 0 ∗/
struct sockaddr ∗ adresse , /∗ Pointeur sur adresse d e s t i n a t a i r e ∗/
int longueur_adresse /∗ Longueur a d r e s s e d e s t i n a t a i r e ∗ /
);

La primitive sendto permet d’envoyer un message de taille longueur octets se trouvant à


l’adresse message par une socket ayant pour descripteur descripteur vers la socket d’adresse
pointée par adresse et de longueur longueur_adresse. Cette primitive retourne le nombre
de caractères effectivement envoyés.

1.5 Fermeture
# i n c l u d e < u n i s t d . h>
int close ( int descripteur );

La primitive close ferme le descripteur d’une socket. Cette fermeture peut être bloquante
pour le processus qui la demande dans le cas de sockets stream tant qu’il reste des données

IUT d’Orsay – DUT Informatique 2009 / 2010 Module Système S4 C


Travaux Dirigés no 2 Sockets Datagramme 4/7

non transmises. Lorsque plus aucun descripteur ne permet d’accéder à une socket, celle-ci est
détruite.

2 Exercices
2.1 Exercice 1 : échange simple
En utilisant les sockets datagramme, écrire les programmes C de deux processus présents sur
deux ordinateurs distincts d’adresses IP respectives 192.168.20.211 et 192.168.34.4. Ces
processus s’échangent des messages de la manière suivante : le premier envoie un à un des
entiers non nuls au second, le second renvoie au premier les doubles des valeurs reçues. Lorsque
le premier envoie 0 au second, la communication se termine et toutes les ressources utilisées
sont libérées (écologie oblige !).

2.2 Exercice 2 : client/serveur


On cherche à construire une application serveur capable de traiter les requêtes de plusieurs
clients à la fois. Son travail est de vérifier la validité d’un numéro de carte banquaire : les
clients lui envoient trois nombres, un premier de type long long int pour le numéro de
carte, un second de type int pour la date d’expiration et un troisième de type int pour le
cryptogramme. Le serveur envoie sa réponse de type int : 1 pour valide, 0 pour invalide. Ce
service sera proposé sur la machine cbvalidity.ebank.eu sur le port 5000.
Écrire les programmes C correspondant au serveur et à un client. Les communications se feront
via sockets datagramme. Dans le cadre de l’exercice, la validité du numéro de carte banquaire
sera décidé aléatoirement.

3 Entraînement : exercice corrigé


3.1 Énoncé : ls -l distant **
On cherche à réaliser une application client-serveur dont le client transmet un nom de fichier au
serveur et récupère le résultat de la commande ls -l exécutée pour ce fichier sur la machine
du serveur. Le programme client prend pour argument l’adresse IP et le port du serveur ansi
qu’un nom de fichier. Le programme serveur prend en argument le numéro de port auquel il
doit s’attacher. Écrivez les codes d’un client et du serveur.

Rappels utiles de Système S2 :


1. Pour exécuter un nouveau programme dans un processus, on peut utiliser la primitive
execlp. Le nouveau programme recouvre alors l’ancien et il n’est jamais possible d’y
revenir. Le prototype de execlp est le suivant :
# i n c l u d e < u n i s t d . h>
int execlp (
c o n s t char ∗ f i l e , / ∗ Nom du f i c h i e r e x e c u t a b l e ∗ /
c o n s t char ∗ a r g 0 , / ∗ Nom du f i c h i e r e x e c u t a b l e ( b i s ) ∗ /
c o n s t char ∗ a r g 1 , / ∗ Premier argument ∗ /
...
c o n s t char ∗ argN , / ∗ N−i e m e a r g u m e n t ∗ /
NULL / ∗ NULL ( f i n d e s a r g u m e n t s ) ∗ /
);

Cette primitive renvoie -1 en cas d’échec (et rien bien sûr en cas de réussite car on ne
revient jamais au programme initial). Son premier argument désigne un fichier exécu-
table. Les arguments suivants sont les options à donner au fichier exécutable, à ceci près

IUT d’Orsay – DUT Informatique 2009 / 2010 Module Système S4 C


Travaux Dirigés no 2 Sockets Datagramme 5/7

que le premier argument arg0 sera une nouvelle fois le nom du fichier exécutable, et le
dernier sera le pointeur NULL pour indiquer la fin des options. Par exemple l’appel de la
commande ps -a listant tous les processus se fera ainsi :
e x e c l p ( " p s " , " p s " , "−a " ,NULL ) ;

2. Lorsque l’on veut rediriger les entrée et sortie standards, on utilise les primitives dup et
close. La primitive close est décrite en section 1.5, le prototype de dup est :
# i n c l u d e < f c n t l . h>
i n t dup ( i n t d e s c r i p t e u r ) ;

Cette primitive renvoie un descripteur ayant exactement les mêmes caractéristiques que
celui passé en argument et ayant la plus petite valeur possible. En cas d’échec, elle re-
tourne -1. Rappelons que le descripteur de l’entrée standard est 0 et celui de la sortie
standard est 1. Si on cherche par exemple à ce que que la sortie standard (où sont impri-
més les résultats de la commande ps -a par exemple) soit redirigée en écriture sur un
tube, on agirait de la manière suivante :
pipe ( tube ) ; / ∗ C r e a t i o n d ’ un t u b e ∗ /
close (1); / ∗ F e r m e t u r e de l a s o r t i e s t a n d a r d ∗ /
dup ( t u b e [ 1 ] ) ; / ∗ On d u p l i q u e l e d e s c r i p t e u r du t u b e en e c r i t u r e ,
∗ l a c o p i e a u r a donc l e p l u s p e t i t d e s c r i p t e u r
∗ l i b r e : 1 ( l i b e r e j u s t e avant ) .
∗/
close ( tube [ 1 ] ) ; / ∗ On f e r m e l e t u b e en e c r i t u r e i n u t i l e a p r e s e n t ∗ /

3.2 Correction (essayez d’abord ! ! !)


Le client de cette application fait simplement un envoi et une reception. Le serveur est plus
complexe : après chaque requête il crée un tube un fils. Le fils redirigera la sortie standard
vers l’écriture sur le tube et lancera la commande ls -l grâce à la primitive execlp. De cette
manière le résultat de ls -l sera écrit dans le tube. Le père attendra la mort de son fils pour
lire le résultat dans le tube et l’envoyer au client.
Des codes possibles sont fournis ci-après, le premier est celui du serveur et le suivant celui
d’un client. Ces codes ne contiennent pas les tests d’échec des différentes primitives. Ils sont à
rajouter dans tout travail sérieux.

IUT d’Orsay – DUT Informatique 2009 / 2010 Module Système S4 C


Travaux Dirigés no 2 Sockets Datagramme 6/7

/ ∗ SERVEUR . Donner l e p o r t d ’ a t t a c h e m e n t du p r o c e s s u s en argument , ∗/


/ ∗ p a r e x e m p l e " e x o 2 _ s e r v e u r 5 0 0 0 " , l a n c e r ce programme en p r e m i e r . ∗ /

# include < s t d i o . h> / ∗ F i c h i e r s d ’ en− t e t e c l a s s i q u e s ∗ /


# include < s t d l i b . h>
# include < u n i s t d . h>
# include < s t r i n g . h>
# include < s y s / t y p e s . h>

# include < s y s / s o c k e t . h> / ∗ F i c h i e r s d ’ en− t e t e " r e s e a u " ∗ /


# include < n e t i n e t / i n . h>
# include < a r p a / i n e t . h>
# include < n e t d b . h>

# define MAX_CHAINE 4096 / ∗ T a i l l e maximum d e s c h a i n e s de c a r a c t e r e s ∗ /

i n t main ( i n t a r g c , char ∗ a r g v [ ] ) {
in t id_socket , / ∗ D e s c r i p t e u r de l a s o c k e t ∗ /
son_addrlen , / ∗ L o n g u eu r de l ’ a d r e s s e du c l i e n t ∗ /
tube [ 2 ] ; / ∗ D e s c r i p t e u r s du t u b e de c o m m u n i c a t i o n ∗ /
char f i c h i e r [MAX_CHAINE ] , / ∗ Nom du f i c h i e r l u ∗ /
r e p o n s e [MAX_CHAINE ] ; / ∗ R ep o n s e de l a commande " l s − l " ∗ /
s t r u c t s o c k a d d r _ i n mon_addr , / ∗ Mon a d r e s s e ∗ /
s o n _ a d d r ; / ∗ A d r e s s e du c l i e n t ∗ /

/ ∗ C r e a t i o n de l a s o c k e t e t m i s e de s o n i d e n t i f i c a t e u r d a n s i d _ s o c k e t ∗ /
i d _ s o c k e t = s o c k e t ( AF_INET ,SOCK_DGRAM, 0 ) ;

/ ∗ D e f i n i t i o n de l ’ a d r e s s e d ’ a t t a c h e m e n t ∗ /
memset ( ( char ∗)& mon_addr , ’ 0 ’ , s i z e o f ( mon_addr ) ) ;
mon_addr . s i n _ f a m i l y = AF_INET ;
mon_addr . s i n _ p o r t = h t o n s ( a t o i ( a r g v [ 1 ] ) ) ;
mon_addr . s i n _ a d d r . s _ a d d r = h t o n l (INADDR_ANY ) ;

/ ∗ A t t a c h e m e n t de l a s o c k e t ∗ /
b i n d ( i d _ s o c k e t , ( s t r u c t s o c k a d d r ∗)& mon_addr , s i z e o f ( mon_addr ) ) ;

while ( 1 ) {
memset ( f i c h i e r , ’ \ 0 ’ ,MAX_CHAINE ) ; / ∗ Mise a z e r o d e s d eu x c h a i n e s ∗ /
memset ( r e p o n s e , ’ \ 0 ’ ,MAX_CHAINE ) ;

p r i n t f ( " En a t t e n t e de r e q u e t e s ! \ n " ) ; /∗ Reception requete ∗/


son_addrlen = s i z e o f ( son_addr ) ; / ∗ I n i t i a l i s a t i o n de s o n _ a d d r l e n ∗ /
r e c v f r o m ( i d _ s o c k e t , f i c h i e r , MAX_CHAINE, 0 ,
( s t r u c t s o c k a d d r ∗)& s o n _ a d d r ,& s o n _ a d d r l e n ) ;
p r i n t f ( " R e q u e t e : %s \ n " , f i c h i e r ) ;
pipe ( tube ) ; / ∗ C r e a t i o n du t u b e de c o m m u n i c a t i o n ∗ /

i f ( f o r k ( ) == 0 ) { /∗ C r e a t i o n d ’ un p r o c e s s u s f i l s ∗ /
close ( 1 ) ; /∗ R edir ection s o r t i e standard ∗/
dup ( t u b e [ 1 ] ) ;
close ( tube [ 1 ] ) ;
e x e c l p ( " l s " , " l s " , "−l " , f i c h i e r , NULL ) ; / ∗ E x e c u t i o n de " l s − l " ∗ /
exit (1); /∗ S o r t i e s u r e r r e u r s i on a r r i v e i c i ∗ /
}

close ( tube [ 1 ] ) ; /∗ Fermeture e c r i t u r e i n u t i l e pour l e pere ∗/


w a i t (NULL ) ; / ∗ A t t e n t e de l a f i n du f i l s " l s −l " ∗ /
r e a d ( t u b e [ 0 ] , r e p o n s e , MAX_CHAINE ) ; / ∗ L e c t u r e du r e s u l t a t d a n s l e t u b e ∗ /
p r i n t f ( " E n v o i de : \ n%s \ n " , r e p o n s e ) ; /∗ Emission reponse ∗/
s e n d t o ( i d _ s o c k e t , r e p o n s e , MAX_CHAINE, 0 ,
( s t r u c t s o c k a d d r ∗)& s o n _ a d d r , s i z e o f ( s o n _ a d d r ) ) ;
close ( tube [ 0 ] ) ; /∗ Fermeture l e c t u r e pour l e pere ∗/
}

close ( id_socket ) ; / ∗ F e r m e t u r e de l a s o c k e t p o u r l e p e r e ∗ /
return 0;
}

IUT d’Orsay – DUT Informatique 2009 / 2010 Module Système S4 C


Travaux Dirigés no 2 Sockets Datagramme 7/7

/ ∗ CLIENT . Donner l ’ IP , l e p o r t du s e r v e u r e t l e nom du f i c h i e r en a r g u m en ts , ∗ /


/ ∗ p a r e x e m p l e " e x o 2 _ c l i e n t 1 2 7 . 0 . 0 . 1 5000 / b i n / l s " . L a n cer en d e r n i e r . ∗ /

# include < s t d i o . h> / ∗ F i c h i e r s d ’ en− t e t e c l a s s i q u e s ∗ /


# include < s t d l i b . h>
# include < s t r i n g . h>
# include < s y s / t y p e s . h>

# include < s y s / s o c k e t . h> / ∗ F i c h i e r s d ’ en− t e t e " r e s e a u " ∗ /


# include < n e t i n e t / i n . h>
# include < a r p a / i n e t . h>
# include < n e t d b . h>

# define MAX_CHAINE 4096 / ∗ T a i l l e maximum d e s c h a i n e s de c a r a c t e r e s ∗ /

i n t main ( i n t a r g c , char ∗ a r g v [ ] ) {
in t id_socket , /∗ D e s c r i p t e u r de l a s o c k e t ∗ /
son_addrlen ; /∗ V a l i d i t e du co d e de c a r t e b a n c a i r e ∗ /
char r e p o n s e [MAX_CHAINE ] ; /∗ R ep o n s e de l a commande " l s − l " ∗ /
s t r u c t s o c k a d d r _ i n mon_addr , /∗ Mon a d r e s s e ∗ /
son_addr ; /∗ A d r e s s e du s e r v e u r ∗ /

/ ∗ C r e a t i o n de l a s o c k e t e t m i s e de s o n i d e n t i f i c a t e u r d a n s i d _ s o c k e t ∗ /
i d _ s o c k e t = s o c k e t ( AF_INET ,SOCK_DGRAM, 0 ) ;

/ ∗ D e f i n i t i o n de l ’ a d r e s s e d ’ a t t a c h e m e n t ∗ /
memset ( ( char ∗)& mon_addr , ’ 0 ’ , s i z e o f ( mon_addr ) ) ;
mon_addr . s i n _ f a m i l y = AF_INET ;
mon_addr . s i n _ p o r t = h t o n s ( 0 ) ; / ∗ On l a i s s e l e s y s t e m e c h o i s i r l e p o r t ∗ /
mon_addr . s i n _ a d d r . s _ a d d r = h t o n l (INADDR_ANY ) ;

/ ∗ D e f i n i t i o n de l ’ a d r e s s e de l ’ a u t r e p r o c e s s u s ∗ /
memset ( ( char ∗)& s o n _ a d d r , ’ 0 ’ , s i z e o f ( s o n _ a d d r ) ) ;
s o n _ a d d r . s i n _ f a m i l y = AF_INET ;
son_addr . s i n _ p o r t = htons ( a t o i ( argv [ 2 ] ) ) ;
son_addr . s in _ ad d r . s_addr = i n e t _ a d d r ( argv [ 1 ] ) ;

/ ∗ A t t a c h e m e n t de l a s o c k e t ∗ /
b i n d ( i d _ s o c k e t , ( s t r u c t s o c k a d d r ∗)& mon_addr , s i z e o f ( mon_addr ) ) ;

p r i n t f ( " Emission . \ n" ) ; /∗ Emission r equete ∗/


sendto ( id_socket , argv [ 3 ] , s t r l e n ( argv [ 3 ] ) +1 , 0 ,
( s t r u c t s o c k a d d r ∗)& s o n _ a d d r , s i z e o f ( s o n _ a d d r ) ) ;

p r i n t f ( " En a t t e n t e . \ n " ) ; /∗ Reception reponse ∗/


s o n _ a d d r l e n = s i z e o f ( s o n _ a d d r ) ; / ∗ I n i t i a l i s a t i o n de s o n _ a d d r l e n ∗ /
r e c v f r o m ( i d _ s o c k e t , r e p o n s e , MAX_CHAINE, 0 ,
( s t r u c t s o c k a d d r ∗)& s o n _ a d d r ,& s o n _ a d d r l e n ) ;
p r i n t f ( " Reponse : \ n%s \ n " , r e p o n s e ) ;

close ( id_socket ) ; / ∗ F e r m e t u r e de l a s o c k e t ∗ /
return 0;
}

IUT d’Orsay – DUT Informatique 2009 / 2010 Module Système S4 C

Vous aimerez peut-être aussi