COMPTE
RENDU DE TELEINFORMATIQUE N°4
Nous
avons choisi de traiter l'application du talk.
On
utilisera le mode de communication connecté car on veut un transport par le
protocole TCP. On échangera des caractères, qui sont codés comme des octets donc on a bien un échange de type flux
d'octets. De plus on veut une connexion fiable, car il ne faudrait pas que le
caractère que l'on transmet soit perdu ou qu'il soit modifié.
On
utilisera un serveur parallèle. Ce serveur est tout à fait en adéquation avec
le mode connecté. Le temps de réponse est régulier, ce qui nous convient car il
ne faut pas que les caractères que l'on tape s'affichent sur l'écran distant
par sacccades ou par paquets.
/**************************************************************************/*
programme SERVEUR */
/**************************************************************************
#include<stdio.h> //appel
des librairies dont on aura besoin
#include <curses.h>
#include<sys/signal.h>
#include<sys/wait.h>
#include
"fon.h" /*
Primitives de la boite a outils */
#define
SERVICE_DEFAUT "1111"
#define
PROTOCOLE_DEFAUT "udp"
void
serveur_appli (char *service, char* protocole); /* programme serveur */
/******************************************************************************/
/*----------------
programme serveur ------------------------------*/
main(int
argc,char *argv[])
{
char *service= SERVICE_DEFAUT; /* numero
de service par defaut */
char *protocole= PROTOCOLE_DEFAUT; /*
protocole par defaut */
/* Permet de passer un nombre de parametre
variable a l'executable */
switch (argc)
{
case 1:
printf("defaut service = %\n", service);
printf("defaut protocole = %\n", protocole);
break;
case 2:
service=argv[1];
printf("defaut protocole = %s\n",
protocole);
break;
case 3 :
service=argv[1];
protocole=argv[2];
break;
default :
printf("Usage:serveur service (nom ou port) protocole (TCP
ou UDP)\n");
exit(1);
}
/* service est le service (ou numŽro de
port) auquel sera affectŽ
ce serveur*/
/* protocole est le protocole qui sera
utilisŽ */
serveur_appli(service, protocole);
}
/******************************************************************************/
void
serveur_appli(char *service, char *protocole)
/*
Procedure correspondant au traitemnt du serveur de votre application */
{
int
masocket; /* N° de la socket */
struct sockaddr_in adr_local;
struct
sockaddr_in *p_adr_local; /*pointeur
sur une adresse locale */
struct
sockaddr_in p_adr_client; /* adresse du client distant */
int
descripteur; /*indique le descripteur
d'une nouvelle socket*/
int val;
/*indique si on a le père ou le fils */
int
process; /*Numero du processus en court
(père ou fils) */
char
tampon; /*variable contenant le
caractère courant */
char
nom_serveur[30]; /*nom du serveur */
int nb_car, nb_octets;
masocket = h_socket(AF_INET, SOCK_STREAM);
/*on
crée une socket ayant pour N° masocket.son domaine est AF_INET. SOCK_STREAM
correspond au mode connecté.*/
gethostname(&nom_serveur, 30);
/*recupère
l'adresse internet de la machine serveur*/
adr_socket("0",nom_serveur,
"tcp",&adr_local, SERVEUR);
/*renseignement
des adresses d'une socket.
nom_serveur
correspond à l'adresse internet de la machine serveur
"tcp"
est le protocole de communication
&adr_local
est un pointeur sur l'adresse socket à renseigner
SERVEUR
est le type de processus */
h_bind(masocket,&adr_local);
/*on
associe a la socket de N° masocket l'adresse locale adr_local */
h_listen(masocket,
100);
/*la
socket de N° masocket est mise en état d'ecoute de demande de connexion. Ici on
peut avoir au maximum 100 requetes en attente. */
/******************************************************************/
/*
établissement de la connexion */
descripteur
= h_accept(masocket,TOUT_CLIENT);
/*acceptation
d'une demande de connexion
descripteur
est le N° d'une socket qui sera utilisé
par le processus serveur pour l'échange
de données avec le processus client. */
process
= fork();
/*creation
d'un processus fils */
tampon
= 'k';
/*
on initialise la variable tampon à une valeur differente de § */
/**************************************************************/
/*ECHANGE
DE DONNEES */
if
(process ==0) /*on traite le cas du processus fils*/
{while (! (tampon
=='§'))
/*§
est la caractère qui nous fait sortir de la boucle */
{ nb_car = h_reads(masocket,&tampon,1);
/*on
recupere les octets transmis. Ici c'est un caractère */
printf("%c",tampon);
/*affichage à l'écran du caractère contenu dans la
variable tampon */
};
}
else /*traitement du processus pere */
{while (! (tampon ==
'§'))
/*§
est la condition d'arret*/
{tampon=getch();
/*tampon
contient la caractere qui a ete tape à
l'écran*/
nb_car = h_writes(masocket,&tampon,1);
/*on
envoie l'octet tampon à travers la socket de N° masocket */
}
}
h_close(masocket);
/*desallocation
de la socket masocket.
}
================================================================
Partie
Client
/**************************************************************************/* Application:
... */
/**************************************************************************/*
programme CLIENT
*/
/**************************************************************************
#include
<stdio.h>
#include
<curses.h> /* Primitives de gestion d'ecran */
#include <sys/signal.h>
#include <sys/wait.h>
#include
"fon.h" /*
primitives de la boite a outils */
#define
SERVICE_DEFAUT "1111"
#define
PROTOCOLE_DEFAUT "udp"
#define
SERVEUR_DEFAUT "localhost"
void
client_appli (char *serveur, char *service, char *protocole);
/**************************************************************************/*---------------
programme client -----------------------*/
main(int
argc, char *argv[])
{
char *serveur= SERVEUR_DEFAUT; /* serveur
par defaut */
char *service= SERVICE_DEFAUT; /* numero
de service par defaut (no de port) */
char *protocole= PROTOCOLE_DEFAUT; /*
protocole par defaut */
/* Permet de passer un nombre de parametre
variable a l'executable */
switch(argc)
{
case 1 : /* arguments par defaut */
printf("serveur par defaut: %\n",serveur);
printf("service par defaut: %\n",service);
printf("protocole par defaut: %\n",protocole);
break;
case
2 : /*
serveur renseigne */
serveur=argv[1];
printf("service par defaut: %\n",service);
printf("protocole par defaut: %\n",protocole);
break;
case
3 : /*
serveur, service renseignes */
serveur=argv[1];
service=argv[2];
printf("protocole par defaut: %\n",protocole);
break;
case
4: /* serveur, service, protocole renseignes */
serveur=argv[1];
service=argv[2];
protocole=argv[3];
break;
default:
printf("Usage:client serveur(nom ou @IP) service (nom ou port)
protocole (TCP ou UDP)\n");
exit(1);
}
/* serveur est le nom (ou l'adresse IP)
auquel le client va acceder */
/* service le numero de port sur le
serveur correspondant au */
/* service desire par le client */
/* protocole le protocole qui sera utilise
pour la communication */
client_appli(serveur,service,protocole);
}
/*************************************************************************/void
client_appli (char *serveur,char *service,char *protocole)
{
int masocket;
/*numéro d’une socket */
struct sockaddr_in *adr_dist, *adr_locale;
int
socketserveur;/*numéro de la socket
serveur */
char
*nom_machine;
int
process; /* numéro du processus
courant */
char
tampon ="a"; /*caractère courant que l’on a tapé à l’écran, initialisé à une valeur
différente de § */
int longueur;
masocket = h_socket(AF_INET,SOCK_STREAM);
/*
allocation de masocket,recuperation de son numero*/
/*renseignement
adresse locale :
recuperation
du nom (adresse IP) de la machine sur laquelle tourne le programme*/
gethostname(nom_machine,30); /*récupération du nom de la machine locale
*/
adr_socket("0",nom_machine,"tcp",&adr_locale,CLIENT);
/*rempli
l'adresse locale*/
h_bind(masocket,&adr_locale);
/*on
associe a la socket de N° masocket l'adresse locale adr_local */
adr_socket(
service,serveur,"tcp",&adr_dist,CLIENT);
/*renseignement
des adresses d'une socket.
serveur
correspond à l'adresse internet de la machine serveur
"tcp"
est le protocole de communication
&adr_local
est un pointeur sur l'adresse socket à renseigner
CLIENT
est le type de processus*/
***********************************************************************
/*
établissement de la connexion */
h_connect(masocket,&adr_dist);
/*demande
de connection au serveur*/
/*ECHANGE
DE DONNEES variable tampon à une valeur differente de § */
/**************************************************************/*/
process
= fork();
/*creation
d'un processus fils */
while
( !(tampon = "§")) )) /*§ est la caractère qui nous fait sortir de la
boucle */
{
if (process == 0 ) /*processus fils*/
{ longueur = h_reads(masocket,tampon,1);
/*on
recupere les octets transmis. Ici c'est un caractère */
printf("%c", tampon);
/*affichage à l'écran du caractère contenu dans la
variable tampon */
}
else
/*processus pere*/
{
h_writes(masocket,tampon,1);
/*on
envoie l'octet tampon à travers la socket de N° masocket */
}
}
h_close(masocket);
/*desallocation
de la socket masocket.*/
}
/*************************************************************************/