Vous êtes sur la page 1sur 15

Lyce polyvalent DIDEROT

61, rue David dAngers


75019 PARIS

Dpartement IRIS

http://www.diderot.org

TP n5

Rseaux Client / Serveur en C


Travail autour d'un programme client/serveur
Auteur
G.VALET
Description plus complte

Version - Date
Version 1.2 - Sept 2008

Nom du fichier
TP-5-Reseaux-Client-serveur.docx

TP n5

Rseaux Client / Serveur en C

Version 1.2 - Sept 2008

A. Sommaire
A. SOMMAIRE.................................................................................................................................................................................. 2
B. OBJECTIFS ................................................................................................................................................................................... 3
C. ETUDE DU CLIENT.......................................................................................................................................................................... 3
C.1. Cration du socket ........................................................................................................................................................... 3
C.2. Programme principal ....................................................................................................................................................... 4
a. Vue densemble ............................................................................................................................................................................................ 4
b. Paramtres.................................................................................................................................................................................................... 4
c. Boucle de fond .............................................................................................................................................................................................. 4
d. Slection de descripteurs ............................................................................................................................................................................ 4
e. Algorigramme ............................................................................................................................................................................................... 5
f. Taille des buffers ........................................................................................................................................................................................... 6

C.3. Mise en uvre et modification du client.......................................................................................................................... 6


a. Test du client................................................................................................................................................................................................. 6
b. Modification du client .................................................................................................................................................................................. 6

D. ETUDE DU SERVEUR....................................................................................................................................................................... 6
D.1. Structure du programme ................................................................................................................................................. 6
D.2. Cration du socket server ................................................................................................................................................ 7
a. Paramtre SO_REUSEADDR ................................................................................................................................................................... 7
b. Ecoute de port .............................................................................................................................................................................................. 7

D.3. Programme principal ....................................................................................................................................................... 7


a. Fonctionnement gnral.............................................................................................................................................................................. 7
b. Fonction main ............................................................................................................................................................................................... 8
c. Communication avec les clients ................................................................................................................................................................ 10
d. Modification du serveur ............................................................................................................................................................................ 10

E. ANNEXE 1 : PROGRAMME CLIENT .................................................................................................................................................. 11


F. ANNEXE 2 : PROGRAMME SERVEUR ................................................................................................................................................ 13

Rseaux Client / Serveur en C - G.VALET Reproduction interdite

2 / 15

TP n5

Rseaux Client / Serveur en C

Version 1.2 - Sept 2008

B. Objectifs
Cest de comprendre le fonctionnement des sockets TCP en langage C. Pour y arriver, il sagira dtudier
et de mettre en uvre un programme ralisant une application client/serveur.
Le listing du programme tudier est en annexe. Il sagit du programme dexemple dtaill dans le cours
Cours et Travaux pratiques en C A. Lebret .
Le programme est en 2 parties : La partie client (client.c) et la partie serveur (serveur.c).

C. Etude du client
C.1. Cration du socket
Quelle partie du programme est-elle charge dinitialiser le socket client ?
Lignes : ____________
Quel est le rle de la fonction inet_addr ? Expliquez la signification et le rle des paramtres et de la
valeur de retour de cette fonction :

Dessinez un petit algorigramme correspondant aux lignes 26 41 du programme client :

Rseaux Client / Serveur en C - G.VALET Reproduction interdite

3 / 15

TP n5

Rseaux Client / Serveur en C

Version 1.2 - Sept 2008

A quoi sert prcisment la fonction memcpy utilise la ligne 46 et quel rle remplit-elle dans le
programme (Voir le dtail de la structure hostent ).

C.2. Programme principal


a. Vue densemble
Compltez le schma suivant des entres sorties du programme client.c et prcisez les interactions avec
les priphriques :
....
..
...

Client.c

b. Paramtres
Quels sont les paramtres passs au programme et comment sont-ils utiliss ?

c. Boucle de fond
Expliquez la particularit de la boucle for et lincidence sur la dure du programme.

d. Slection de descripteurs
Donnez la dfinition dun descripteur de fichiers (file handle) et prcisez avec quels descripteurs le
programme va-t-il travailler ?

Rseaux Client / Serveur en C - G.VALET Reproduction interdite

4 / 15

TP n5

Rseaux Client / Serveur en C

Version 1.2 - Sept 2008

e. Algorigramme
Compltez lalgorigramme suivant reprsentant le fonctionnement du programme principal

non

3 arguments ?
oui
Initialiser Socket

Ecoute socket
Ecoute clavier
Sel.
Descripteurs
ok ?
oui
oui

non

FIN

Rception
Socket ?

Lecture caractres
depuis socket

non
oui

Lecture
clavier ?

Lecture
caractres

Rseaux Client / Serveur en C - G.VALET Reproduction interdite

non

5 / 15

TP n5

Rseaux Client / Serveur en C

Version 1.2 - Sept 2008

f. Taille des buffers


Indiquez la taille en octets des buffers clavier et socket telle quelle est dfinie dans le programme.
Rponse :

C.3. Mise en uvre et modification du client


a. Test du client
Lobjectif est dexcuter le programme client ET serveur sur la mme machine afin de tester son bon
fonctionnement.
Compilez et excutez le client ET le serveur. Le client doit tenter de se connecter au serveur sur la machine
locale

b. Modification du client
Vous allez modifier le client afin dajouter une commande permettant de quitter. Cette commande
permettra au client de fermer la connexion et stopper le programme ds que le client tape la chane
/quit .
Pour cela, il faut effectuer une comparaison de chanes entre le texte saisi par lutilisateur et la chaine
/quit qui sert quitter.
Modifiez le client afin quil prenne en charge la commande /quit . Testez et validez le fonctionnement.

Les fonctions stcmp ou strncmp peuvent tre utilises pour comparer des chanes.

D. Etude du serveur
D.1. Structure du programme
Observez le code source serveur.c et indiquez le nom et le rle de chaque fonction (main, serveur et
socket_serveur) en compltant le tableau suivant :

Fonction

Paramtres

Rle

Rseaux Client / Serveur en C - G.VALET Reproduction interdite

6 / 15

TP n5

Rseaux Client / Serveur en C

Version 1.2 - Sept 2008

D.2. Cration du socket server


Quelles sont les diffrences majeures entre un socket client et un socket serveur (en termes dadresses IP et
de ports) ?

Reprez, dans le code source, la cration du socket serveur. Quelle est la diffrence avec la cration dun
socket client ?

a. Paramtre SO_REUSEADDR
Lors de la cration du socket serveur, un paramtre SO_REUSEADDR est utilis.
A quoi sert ce paramtre et dans quel(s) cas sera-t-il le plus utile ?

b. Ecoute de port
Quelles sont les 2 oprations effectuer pour que le socket serveur nouvellement cr puisse couter et
accepter les connexions venant des clients ?

D.3. Programme principal


a. Fonctionnement gnral
Le programme principal va crer un processus enfant pour chaque client connect. Le client aura donc
une relation privilgie avec le serveur. La communication avec chaque client se fera dans un processus
diffrent concurrent.
Quel est lintrt principal de crer un processus enfant pour chaque client ?

Rseaux Client / Serveur en C - G.VALET Reproduction interdite

7 / 15

TP n5

Rseaux Client / Serveur en C

Version 1.2 - Sept 2008

b. Fonction main
Voici lalgorigramme de la fonction main
Compltez cet algorigramme en vous aidant du listing du programme serveur

Rseaux Client / Serveur en C - G.VALET Reproduction interdite

8 / 15

TP n5

Rseaux Client / Serveur en C

Rseaux Client / Serveur en C - G.VALET Reproduction interdite

Version 1.2 - Sept 2008

9 / 15

TP n5

Rseaux Client / Serveur en C

Version 1.2 - Sept 2008

c. Communication avec les clients


A ce stade, le serveur gre chaque communication de la manire que le client. On retrouve donc, dans la
fonction serveur() la mme gestion des entres/sorties (Clavier et socket).
Daprs le listing de la fonction serveur , dans quelle situation la boucle for sera stoppe ?

d. Modification du serveur
Vous allez modifier le serveur afin dajouter une commande permettant de quitter. Cette commande
permettra au serveur de fermer la connexion avec un client et de stopper le programme.
Pour cela, il faut effectuer une comparaison de chanes entre le texte saisi par lutilisateur et la chaine
/quit qui sert quitter.
Modifiez le serveur afin quil prenne en charge la commande /quit . Testez et validez le fonctionnement.

Les fonctions stcmp ou strncmp peuvent tre utilises pour comparer des chanes.

Rseaux Client / Serveur en C - G.VALET Reproduction interdite

10 / 15

TP n5

Rseaux Client / Serveur en C

Version 1.2 - Sept 2008

E. Annexe 1 : Programme Client


client.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

/*
* Client en C
*
* A.LEBRET
*/
#include <sys/types.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
/*---------------------------------------------- */
int socket_client( char *serveur , unsigned short port ) {
int client_socket ;
struct hostent *hostent ;
struct sockaddr_in serveur_sockaddr_in ;
client_socket = socket( PF_INET , SOCK_STREAM , 0 ) ;
if ( client_socket == -1 ) {
perror( "socket" ) ;
exit( EXIT_FAILURE ) ;
}
if ( inet_addr( serveur ) == INADDR_NONE ) /* nom */ {
hostent = gethostbyname( serveur ) ;
if ( hostent == NULL ) {
perror( "gethostbyname" ) ;
exit( EXIT_FAILURE ) ;
}
}
else /* adresse IP */ {
unsigned long addr = inet_addr( serveur ) ;
hostent = gethostbyaddr((char *)&addr, sizeof(addr),
AF_INET ) ;
if ( hostent == NULL ) {
perror( "gethostbyaddr" ) ;
exit( EXIT_FAILURE ) ;
}
}
memset(&serveur_sockaddr_in, 0,
sizeof(serveur_sockaddr_in));
serveur_sockaddr_in.sin_family = AF_INET ;
serveur_sockaddr_in.sin_port = htons(port) ;
memcpy( &serveur_sockaddr_in.sin_addr.s_addr ,
hostent->h_addr_list[0] ,
hostent->h_length) ;
printf( ">>> Connexion vers le port %d de %s [%s]\n" ,
port , hostent->h_name ,
inet_ntoa( serveur_sockaddr_in.sin_addr ) ) ;
if ( connect(client_socket,
(struct sockaddr *)&serveur_sockaddr_in,
sizeof(serveur_sockaddr_in)) == -1 ) {
perror( "connect" ) ;

Rseaux Client / Serveur en C - G.VALET Reproduction interdite

11 / 15

TP n5
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

Rseaux Client / Serveur en C

Version 1.2 - Sept 2008

exit( EXIT_FAILURE ) ;
}
return client_socket ;
}
/*---------------------------------------------- */
int main(int argc , char **argv) {
char *serveur ;
unsigned short port ;
int client_socket ;
if ( argc != 3 ) {
fprintf(stderr, "usage: %s serveur port\n",
argv[0]);
exit( EXIT_FAILURE ) ;
}
serveur = argv[1] ;
port = atoi( argv[2] ) ;
client_socket = socket_client( serveur , port ) ;
for ( ; ; ) {
fd_set rset ;
FD_ZERO( &rset ) ;
FD_SET( client_socket , &rset ) ;
FD_SET( STDIN_FILENO , &rset ) ;
if (select(client_socket+1, &rset, NULL, NULL, NULL)
== -1 ) {
perror( "select" ) ;
exit( EXIT_FAILURE ) ;
}
if (FD_ISSET(client_socket, &rset)) {
int octets ;
unsigned char tampon[BUFSIZ] ;
octets = read(client_socket, tampon, sizeof(tampon));
if ( octets == 0 ) {
close( client_socket ) ;
exit( EXIT_SUCCESS ) ;
}
write( STDOUT_FILENO , tampon , octets ) ;
}
if ( FD_ISSET( STDIN_FILENO , &rset ) ) {
int octets ;
unsigned char tampon[BUFSIZ] ;
octets = read(STDIN_FILENO, tampon, sizeof(tampon));
if ( octets == 0 ) {
close( client_socket ) ;
exit( EXIT_SUCCESS ) ;
}
write( client_socket , tampon , octets ) ;
}
}
exit( EXIT_SUCCESS ) ;
}

Rseaux Client / Serveur en C - G.VALET Reproduction interdite

12 / 15

TP n5

Rseaux Client / Serveur en C

Version 1.2 - Sept 2008

F. Annexe 2 : Programme serveur


serveur.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

/*
* Serveur en C
*
* A.LEBRET
*/
#include <sys/types.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
/* --------------------------------------------- */
int socket_serveur( unsigned short port ) {
int serveur_socket , option = 1 ;
struct sockaddr_in serveur_sockaddr_in ;
serveur_socket = socket( PF_INET , SOCK_STREAM , 0 ) ;
if ( serveur_socket == -1 ) {
perror( "socket" ) ;
exit( EXIT_FAILURE ) ;
}
if ( setsockopt(serveur_socket, SOL_SOCKET, SO_REUSEADDR,
&option, sizeof(option)) == -1 ) {
perror( "setsockopt" ) ;
exit( EXIT_FAILURE ) ;
}
memset(&serveur_sockaddr_in, 0,
sizeof (serveur_sockaddr_in));
serveur_sockaddr_in.sin_family = AF_INET ;
serveur_sockaddr_in.sin_port = htons( port ) ;
serveur_sockaddr_in.sin_addr.s_addr = INADDR_ANY ;
if ( bind( serveur_socket ,
(struct sockaddr *) &serveur_sockaddr_in,
sizeof(serveur_sockaddr_in) ) == -1 ) {
perror( "bind" ) ;
exit( EXIT_FAILURE ) ;
}
if ( listen( serveur_socket , SOMAXCONN ) == -1 ) {
perror( "listen" ) ;
exit( EXIT_FAILURE ) ;
}
return serveur_socket ;
}
/* ----------------------------------------------------- */
void serveur( int client_socket ) {
for ( ; ; ) {
fd_set rset ;
FD_ZERO( &rset ) ;
FD_SET( client_socket , &rset ) ;
FD_SET( STDIN_FILENO , &rset ) ;
if ( select(client_socket+1, &rset,
NULL, NULL, NULL ) == -1 ) {
perror( "select" ) ;
exit( EXIT_FAILURE ) ;

Rseaux Client / Serveur en C - G.VALET Reproduction interdite

13 / 15

TP n5

Rseaux Client / Serveur en C

Version 1.2 - Sept 2008

58
}
59
if ( FD_ISSET( client_socket , &rset ) ) {
60
int octets ;
61
unsigned char tampon[BUFSIZ] ;
62
octets = read(client_socket, tampon, sizeof(tampon));
63
if ( octets == 0 ) {
64
close( client_socket ) ;
65
printf( ">>> Dconnexion\n" ) ;
66
exit( EXIT_SUCCESS ) ;
67
}
68
write( STDOUT_FILENO , tampon , octets ) ;
69
}
70
if ( FD_ISSET( STDIN_FILENO , &rset ) ) {
71
int octets ;
72
unsigned char tampon[BUFSIZ] ;
73
octets = read(STDIN_FILENO, tampon, sizeof(tampon));
74
if ( octets == 0 ) {
75
close( client_socket ) ;
76
exit( EXIT_SUCCESS ) ;
77
}
78
write( client_socket , tampon , octets ) ;
79
}
80
}
81 }
82 /* ------------------------------------------------ */
83 int main( int argc , char **argv ) {
84
unsigned short port ;
85
int serveur_socket ;
86
if ( argc != 2 ) {
87
fprintf( stderr , "usage: %s port\n" , argv[0] ) ;
88
exit( EXIT_FAILURE ) ;
89
}
90
port = atoi( argv[1] ) ;
91
serveur_socket = socket_serveur( port ) ;
92
for ( ; ; ) {
93
fd_set rset ;
94
FD_ZERO( &rset ) ;
95
FD_SET( serveur_socket , &rset ) ;
96
FD_SET( STDIN_FILENO , &rset ) ;
97
if (select(serveur_socket+1, &rset,
98
NULL, NULL, NULL) == -1 ) {
99
perror( "select" ) ;
100
exit( EXIT_FAILURE ) ;
101
}
102
if ( FD_ISSET( serveur_socket , &rset ) ) {
103
int client_socket ;
104
struct sockaddr_in client_sockaddr_in ;
105
socklen_t taille=sizeof (client_sockaddr_in);
106
struct hostent *hostent ;
107
client_socket = accept( serveur_socket ,
108
(struct sockaddr *) &client_sockaddr_in ,
109
&taille ) ;
110
if ( client_socket == -1 ) {
111
perror( "accept" ) ;
112
exit( EXIT_FAILURE ) ;
113
}
114
switch ( fork( ) ) {
115
case -1 : /* erreur */
116
perror( "fork" ) ;
117
exit( EXIT_FAILURE ) ;
118
case 0 : /* processus fils */
119
close( serveur_socket ) ;

Rseaux Client / Serveur en C - G.VALET Reproduction interdite

14 / 15

TP n5
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139 }
140
141

Rseaux Client / Serveur en C

Version 1.2 - Sept 2008

hostent = gethostbyaddr(
(char *)&client_sockaddr_in.sin_addr.s_addr,
sizeof(client_sockaddr_in.sin_addr.s_addr),
AF_INET) ;
if ( hostent == NULL ) {
perror( "gethostbyaddr" ) ;
exit( EXIT_FAILURE ) ;
}
printf(">>> Connexion depuis %s [%s]\n",
hostent->h_name,
inet_ntoa( client_sockaddr_in.sin_addr ) ) ;
serveur( client_socket ) ;
exit( EXIT_SUCCESS ) ;
default : /* processus pre */
close( client_socket ) ;
}
}
}
exit( EXIT_SUCCESS ) ;

Rseaux Client / Serveur en C - G.VALET Reproduction interdite

15 / 15

Vous aimerez peut-être aussi