DOM INF Module AS
Communications entre processus distants
Mise en oeuvre des sockets
B. Dupouy
Notes préliminaires :
-
Supports de cours au format pdf :
sockets (1,6Mo)
-
Sur une machine "System V" (par exemple, sur Solaris), ajouter les options
suivantes lors de la compilation :
-lsocket (pour charger la bibliothèque des sockets)
-lnsl (pour charger les utilitaires htons...)
-
Les fichiers sources des exemples sont dans :
~domas/sockdir
On enverra le(s) fichier(s) source(s) traitant l'exercice et le
makefile permettant leur bonne utilisation à :
dupouy@enst ou à gadret@enst
Le texte du champ sujet doit contenir le mot : TPDOM
SOMMAIRE
On remarquera sur le schéma suivant :
- sin_port, le numéro de port,
- sin_addr, le(s) numéro(s) Internet de la machine, numéro
attribué par l'administrateur système (un par carte Ethernet sur
la machine)
- le numéro Ethernet de la carte, numéro unique attribué
(matériel) par le constructeur,
C'est sur ce type de canevas que l'on construit de nombreuses applications
distribuées.
Ici, le serveur se contente d'attendre les demandes des clients distants.
La gestion de la
communication sera prise en charge par un processus fils, pendant que le
serveur se remet en attente de demande de connexions d'autres clients.
Schéma de principe, après fin de l'attente sur accept, le serveur
créé un processus fils, ce dernier fermera le socket
d'écoute, tandis que le serveur fermera celui de communications :
Le serveur se libère ainsi de la gestion des communications pour se
consacrer à l'écoute des demandes de connexions. Le nombre
de ces demandes en attente est borné par listen , le
nombre
de communications en parallèle étant, lui, limité
par le nombre de processus que le serveur peut créer :
On vous demande de faire tourner les deux programmes suivants et
d'en comprendre
le fonctionnement afin de pouvoir mener à son terme l'exercice qui vous
est proposé par la suite.
Le serveur sera de préférence lancé :
- sur une machine différente de celle des clients,
- dans une autre fenêtre, sur la machine courante.
On utilisera la commande netstat
ou netstat -P tcp -f inet
pour suivre les dialogues entre
les clients et les serveurs.
Remarques :
-
la fonction socket ne fait qu'allouer les structures de
données nécessaires, mais ne réserve pas de numéro de port. Ce numéro
de port est attribué de façon explicite lors du bind, ou de
façon transparente lors du connect.
-
dans l'exemple proposé, SIGCHLD n'est pas géré. La commande ps permettra
de voir les zombies (processus dans l'état Z)
résultant de la terminaison des processus
qui ont été créés par le serveur.
A faire pour le serveur :
-
Cliquez ici pour le recopier
-
Après l'avoir modifié, vous vérifierez son fonctionnement en l'interrogeant
à l'aide de la commande telnet.
Si les bibliothès réseau manquent, ajouter les options suivantes :
-lsocket (pour charger la bibliothèque des sockets)
-lnsl (pour charger les utilitaires htons...)
Si le serveur est arrêté et relancé peu
de temps après, il ne peut pas reprendre le même port
d'écoute. Pour pouvoir réutiliser immédiatement
ce port il faut utiliser la fonction
setsockopt
(après socket et avant bind) :
setsockopt(..., SOL_SOCKET, SO_REUSEADDR, ... , ... )
A faire pour le client:
-
Cliquez ici pour consulter cli_fork.c.
-
Vérifier que ce client transmet bien au serveur les informations
qu'on lui a données en utilisant le clavier.
-
On peut aussi rediriger stdin (on suppose que le fichier exécutable
s'appelle cli_fork) :
ls -il | cli_fork ... ...
cat *.c | cli_fork ... ...
man ls | cli_fork ... ...
A faire :
-
Faire interroger simultanément le serveur par plusieurs clients
situés sur des machines différentes, ceci pour en vérifier
le fonctionnement parallèle
-
Dans l'exemple proposé pour le serveur, le signal SIGCHLD
n'est pas
géré. La commande ps permettra
de voir les zombies résultant de la terminaison des
processus créés par le serveur.
-
Utiliser la commande netstat
ou netstat -P tcp -f inet
pour tracer les communications entre
clients et serveur. Observer les autres communications entrantes et sortantes.
select permet de se mettre à l'écoute sur
plusieurs fichiers simultanément, c'est à dire de multiplexer
les entrées-sorties.
Nous allons étudier l'écriture d'un serveur
utilisant cette fonction.
Utiliser la commande :
man -s 3c select
pour avoir les détails du fonctionnement de select.
Pour comprendre le mécanisme de cet appel système, on vous demande de compléter le code du client et du
serveur dont on donne les squelettes ci-dessous.
On créera de nombreux processus clients pour constater le bon
fonctionnement du serveur.
Cliquez ici pour consulter sel_serv.file
Cliquez ici pour consulter
sel_cli.file
Il s'agit d'écrire le code d'une application qui attend des
données sur stdin et sur au moins un
port en UDP ou en
TCP. Cette application renvoie tout ce qu'elle recoit
vers un (ou plusieurs) destinataire(s).
Fonctionnement de l'application :
-
le processus se bloque en select sur stdin et le
(ou les) ports d'entrée lus dans le fichier de configuration,
comme cela est fait dans l'exercice précédent,
-
quand il recoit un message sur un port (ou sur stdin) il le renvoie
vers les sites dont il a lu l'adresse IP et le numéro de port
dans le fichier de configuration,
-
on lancera plusieurs processus dans
des fenêtres se trouvant sur des sites
différents et on initialisera la communication en rentrant un
texte au clavier pour l'un des processus,
On donne le canevas du code dans lequel il vous faudra compléter
les parties manquantes, c'est à dire la mise en place du select
et les fonctions de lecture et d'écriture sur les ports. Pour ce faire,
on utilisera les exemples précédents.
Cliquez
ici
pour récupérer le fichier à compléter.
Comment obtenir le(s) port(s) d'entrée et
l'(es) adresse(s) des destinataires :
-
l'application va lire dans un fichier de configuration les
numéros de port sur lesquels elle attend et les couples
(adresse-IP, port)
du (ou des) destinataire(s) vers lequel (ou lesquels) elle émet.
Par exemple, pour construire un anneau
entre M1, M2 et M3, on peut donner les fichiers de configuration suivants :
===Pour le processus qui s'exécute sur M1 :
sortie M3 UDP 30287
entree **** TCP 54678
===Pour le processus qui s'exécute sur M2 :
sortie M1 TCP 54678
entree **** UDP 48521
===Pour le processus qui s'exécute sur M3 :
sortie M2 UDP 48521
entree **** UDP 30287
Que devez-vous faire pour tester votre programme ?
Il faudra construire un anneau en faisant tourner votre programme
sur au moins trois machines différentes.
Pour obtenir un exemple de trois fichiers de configuration, cliquez
ici .
©(Copyright)
dupouy at telecom-paristech.fr