Programmation Répartie - Sockets en C Partie 2 : socket TCP

Transcription

Programmation Répartie - Sockets en C Partie 2 : socket TCP
Programmation Répartie - Sockets en C
Partie 2 : socket TCP
Frédéric Guinand
[email protected]
IUT informatique / Université du Havre
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
TCP : Transmission Control Protocol
mode connecté
comme le téléphone
connexion durable
adresse indiquée une seule fois à l’établissement de la
connexion
exemples : ftp, telnet
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
UDP ↔ TCP
UDP
analogie courrier postal
UDP : le serveur attend des messages en provenance de
plusieurs clients
UDP : à chaque reception, le serveur est disponible pour
une autre connexion
TCP
analogie téléphone
TCP : le serveur établit une connexion qui reste active avec
UN client, durant la connexion le serveur est occupé
TCP : lorsque la connexion entre le client et le serveur
prend fin, le serveur devient disponible de nouveau
TCP : si le serveur est occupé, tout nouveau client doit
attendre son tour pour établir une connexion avec le serveur
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
Principe d’une application Client/Serveur TCP
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
Préparation des sockets pour la connexion
Le client
configuration de la socket server : remplissage des champs
de struct sockaddr_in (avec le numéro IP et le numéro de
port)
création de la socket client : socket()
Le serveur
configuration de la socket
création de la socket
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
Communication entre client et serveur
Rappel UDP
client et serveur attachent leur socket : bind()
dès la fin de la création et de l’attachement de la socket
côté client et de la socket côté serveur, la communication
peut commencer
sendto() et recvfrom()
en TCP c’est différent
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
Communication entre client et serveur
Le client
demande une connexion avec le serveur connect()
si le serveur est occupé, il est mis en attente
Le serveur
attachement de la socket : bind()
le serveur se met à l’écoute des éventuels clients : listen()
lorsqu’un nouveau client arrive, le serveur accepte la
connexion : accept()
⇒ la communication peut maintenant commencer
envoi d’information par write()
reception d’informations par read() (ou recv()
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
bind() ↔ connect()
bind() consiste à attacher la socket à une adresse locale
connect() consiste à attacher la socket à un serveur distant
Le serveur
le serveur doit exécuter un bind(), pour permettre aux
clients de se connecter à lui
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
Eléments communs
les fichiers d’include
la préparation de la socket, la création et l’attachement
fichiers d’include
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
Configuration des informations de la socket
déclaration d’une variable struct sockaddr_in
renseignement des trois champs :
sin_family = AF_INET
sin_addr pour l’adresse IP
sin_port pour le numéro de port
Côté serveur
struct sockaddr_in socket_locale ;
socket_locale.sin_family = AF_INET ;
/*adresse IP sans importance */
socket_locale.sin_addr.s_addr = htonl(INADDR_ANY) ;
/* si le port est 5555 */
socket_locale.sin_port = htons(5555) ;
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
Côté client
le client ne doit configurer qu’une structure sockaddr_in
il doit renseigner les champs de cette structure sockaddr_in
avec les informations de la machine sur laquelle le serveur
est exécuté : numéro IP et numéro de port.
struct sockaddr_in infos_serveur ;
infos_serveur.sin_family = AF_INET ;
// adresse IP du serveur (on suppose que l’adresse vaut 98...)
// sinon il faut utiliser gethostbyname()... vous maîtrisez ça non ?
infos_serveur.sin_addr.s_addr = inet_addr("98.23.68.34") ;
// numéro de port du serveur (on le suppose égal à 5555)
infos_serveur.sin_port = htons(5555) ;
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
Création des sockets
Côté client
int desc ;
if((desc= socket(AF_INET,
SOCK_STREAM,
IPPROTO_TCP)) == -1) {
printf("problème création socket \n") ;
exit(1) ;
}
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
Création des sockets
Côté serveur
int desc ;
if((desc= socket(AF_INET,
SOCK_STREAM,
IPPROTO_TCP)) == -1) {
printf("problème création socket \n") ;
exit(2) ;
}
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
Attachement et préparation à la connexion
Côté serveur
if((bind(desc,
(struct sockaddr *)&socket_locale,
sizeof(socket_locale)) == -1) {
printf("problème au moment de l’attachement \n") ; exit(1) ;
}
// après le bind, le serveur attend une connexion d’un client
if(listen(desc,10) < 0) {
printf("problème au niveau du listen \n") ;
exit(3) ;
}
10 est la longueur maximum de la file des connexions en
attente
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
Connexion
Côté client
if((connect(desc,
(struct sockaddr *)&infos_serveur,
sizeof(infos_serveur)) == -1) {
printf("problème au moment de la connexion \n") ;
exit(4) ;
}
le client attend que la connexion soit acceptée pour engager
les échanges
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
Connexion
Côté serveur
struct sockaddr_in infos_client ;
int lg_infos_client ;
int desc_sock_com ;
if((desc_sock_com=accept(desc,
(struct sockaddr *)&infos_client,
&lg_infos_client) == -1) {
printf("problème au moment de l’acceptation \n") ;
exit(5) ;
}
→ la primitive accept() retourne un nouveau descripteur de
socket
c’est désormais au travers de cette socket que client et
serveur vont communiquer !
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
La communication
si l’exécution de socket, bind, connect, listen et
accept s’est bien passée la communication peut
commencer,
deux primitives sont utilisées pour communiquer :
int nbOctetsRecus = read(desc_socket,buffer,taille_buffer)
int nbOctetsEnvoyes = write(desc_socket,buffer,taille_buffer)
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
En résumé
Côté client
int desc_socket ;
struct sockaddr_in infos_serveur ;
// création socket
desc_socket = socket(AF_INET,SOCK_STREAM,0) ;
// configuration informations serveur
infos_serveur.XXX = YYY ;
// connexion au serveur
connect(desc_socket,&infos_serveur,sizeof(infos_serveur)) ;
// lecture - écriture
while(il y a des échanges) {
write(desc_socket,buffer,sizeofbuffer) ;
read(desc_socket,buffer,sizeobuffer) ;
}
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
Côté serveur
int desc_socket, desc_sock_com ;
struct sockaddr_in infos_client, infos_serveur ;
// création socket, configuration adresse serveur, attachement
desc_socket = socket(AF_INET,SOCK_STREAM,0) ;
infos_serveur.XXX = YYY ;
bind(desc_socket,&infos_serveur,sizeof(infos_serveur)) ;
// attente de connexions et gestion d’une connexion
listen(desc_socket,taille-file-attente) ;
desc_sock_com = accept(desc_socket,
&infos_client,sizeof(infos_client)) ;
// lecture - écriture
while(il y a des échanges) {
read(desc_sock_com,buffer,sizeofbuffer) ;
write(desc_sock_com,buffer,sizeobuffer) ;
}
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
Côté serveur
pour servir plusieurs clients à la suite
// création socket, configuration adresse serveur, attachement
// attente de connexions
listen(desc_socket,taille-file-attente) ;
while(le serveur accepte des connexions) {
desc_sock_com = accept(desc_socket,
&infos_client,sizeof(infos_client)) ;
// lecture - écriture
while(il y a des échanges) {
read(desc_sock_com,buffer,sizeofbuffer) ;
write(desc_sock_com,buffer,sizeobuffer) ;
}
close(desc_sock_com) ;
}
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP
Côté serveur
pour servir plusieurs clients simultanément
// création socket, config adr serveur, attachement, attente
listen(desc_socket,taille-file-attente) ;
while(le serveur accepte des connexions) {
desc_sock_com = accept(desc_socket,
&infos_client,sizeof(infos_client)) ;
pid = fork() ;
if(pid == 0) { // je suis le fils
close(desc_socket) ;
while(il y a des échanges) {
read(desc_sock_com,buffer,sizeofbuffer) ;
write(desc_sock_com,buffer,sizeobuffer) ;
}
close(desc_sock_com) ;
} else { close(desc_sock_com) ; }
}
Frédéric Guinand
Programmation Répartie - Sockets en C Partie 2 : socket TCP

Documents pareils