fichier PowerPoint - Charlie-Soft

Download Report

Transcript fichier PowerPoint - Charlie-Soft

Programmation réseau
Les sockets de Berkeley
BTS IRIS 2
Les sockets
1
Généralités
►
►
Les sockets : modèle permettant la communication inter
processus (IPC - Inter Process Communication) sur un même poste
ou à travers un réseau TCP/IP
Avant leur introduction, le seul mécanisme standard qui permettait à
deux processus de communiquer se faisait par l'intermédiaire des
pipes.
►
Les sockets se situent juste au-dessus de la couche transport
►
Deux modes de communication possibles :
 Le mode connecté, utilisant le protocole TCP
 Le mode non connecté, utilisant le protocole UDP
BTS IRIS 2
Les sockets
2
Plan du cours
► Le
modèle client/serveur
► Présentation des sockets
► Les primitives d’initialisation
► Les primitives d’échange d’information
► Exemples
BTS IRIS 2
Les sockets
3
Le modèle client/serveur
BTS IRIS 2
Les sockets
4
Protocoles de communication
►
Les protocoles de communication (comme TCP/IP)
permettent la communication entre 2 applications
différentes (point-à-point), éventuellement sur 2 postes
différents
►
Le détail du transfert effectif des données est spécifié par
le protocole de communication de la couche transport
mais le moment et la façon dont les applications
interagissent entre elles sont définis par le
programmeur
►
►
Pour la communication point-à-point utilisant un protocole
de type TCP/IP : le modèle client/serveur est le +
utilisé (et le plus simple)
BTS IRIS 2
Les sockets
5
Connexion / Sans connexion
► Il
existe 2 types d’application :
 Applications orientées connexion
 Applications orientées sans connexion
► Applications
orientées connexion :
► Applications
orientées sans connexion :
 protocole sous-jacent en mode connecté : TCP/IP
 protocole fiable
 protocole sous-jacent en mode non connecté : UDP/IP
 vérifications doivent être faites au niveau applicatif
 Protocole non fiable mais rapide
BTS IRIS 2
Les sockets
6
Mode de connexion
► Le
mode connecté :
 ⋍ communication téléphonique
 protocole TCP.
 une connexion durable est établie entre les deux
processus
► l'adresse
de destination n'est pas nécessaire
à chaque envoi de données.
► Il
BTS IRIS 2
faut penser à fermer la connexion
Les sockets
7
Mode de connexion
► Le
mode non connecté
 ⋍ communication par courrier
 protocole UDP
► nécessite
envoi
► aucun
l'adresse de destination à chaque
accusé de réception n'est donné.
 Risque de paquets perdu…
 Ordre des paquets inconnu…
BTS IRIS 2
Les sockets
8
Les sockets
BTS IRIS 2
Les sockets
9
Positionnement dans le modèle OSI
► Les
sockets se situent juste au-dessus de la
couche transport du modèle OSI (protocoles
UDP ou TCP)
Couche application
Application utilisateur
Orientée connexion
Application utilisateur
Orientée sans connexion
sockets
Couche transport
BTS IRIS 2
UDP
TCP
Les sockets
10
Création d’un socket
►
►
►
►
Le concept de socket a été créé pour accomplir les
communications inter-processus (IPC)
Un socket est utilisé pour permettre aux processus de
communiquer entre eux, de la même manière que le
téléphone ou le courrier permet de communiquer entre
plusieurs personnes
Pour attendre des demandes de communications : créer
un socket (sorte de point d’écoute)
Il faut créer un socket avec les bonnes options
BTS IRIS 2
Les sockets
11
Options
►
►
Il faut spécifier son type d’adressage
Les deux types d’adressage les plus répandus :
 AF_UNIX : famille d’adresse UNIX (locale : pas de réseau)
 AF_INET : famille d’adresse Internet (format xx.xx.xx.xx)
►
Il faut spécifier un numéro de port sur la machine
 Ce numéro doit être compris entre 49152 et 65535
►
Il faut spécifier son type
 les deux types les plus répandus sont
SOCK_STREAM : spécifiques au mode connecté (TCP)
► SOCK_DGRAM : spécifiques au mode non-connecté (UDP)
►
BTS IRIS 2
Les sockets
12
Options
► De
la même façon qu’on attribue un numéro de
téléphone à une personne pour recevoir des
appels, il faut spécifier au socket une adresse
à laquelle il doit recevoir les messages qui lui sont
destinés (bind)
► Les
sockets de type SOCK_STREAM ont la
possibilité de mettre les requêtes de
communication dans une file d’attente (listen)
BTS IRIS 2
Les sockets
13
Attente les demandes
► Une
fois créé, le socket va attendre les
demandes de communication (accept)
► Après
la prise en compte de cette demande,
le socket peut se remettre à attendre les
demandes de communication
► Utilisation de Thread ou de fork()
BTS IRIS 2
Les sockets
14
Connexion entre 2 sockets
► Une
fois créé le socket qui reçoit des demandes de
communication, peut être appelé par un autre
socket
► Il faut connecter un socket à un autre socket
qui est en attente (connect)
► Une
fois la connexion établie, la conversation
peut commencer (read, write…)
►À
la fin de la communication (comme on raccroche
le téléphone) il faut fermer le socket qui a servi
à la communication (close)
BTS IRIS 2
Les sockets
15
Les primitives
d’initialisation et de mise en
relation
BTS IRIS 2
Les sockets
16
Initialisation
► Initialisation
des sockets
obligatoire avant utilisation
WSADATA WSAData;
WSAStartup(MAKEWORD(2,0), &WSAData);
//faire WSACleanup(); à la fin de
l’utilisation des sockets
BTS IRIS 2
Les sockets
17
Création du socket
SOCKET sock; //initialiser une variable de type socket
SOCKADDR_IN sin;
//informations techniques du socket
//si serveur :
sin.sin_addr.s_addr = htonl(INADDR_ANY);
//si client :
//sin.sin_addr.s_addr = inet_addr("10.7.9.1"); //adresse serveur
sin.sin_family = AF_INET; //famille du socket
sin.sin_port = htons(4148); //port sur lequel se connecter ou écouter
// ports réservés
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //création du
socket TCP/IP
//1er paramètre : famille du socket
//2ième paramètre : type de socket
//3ième paramètre : protocole IP
BTS IRIS 2
Les sockets
18
Relier le socket à l’adresse et au port
bind(sock, (SOCKADDR *) &sin, sizeof(sin));
► Attache
le socket directement au port et
à l'adresse définis dans sin
► Trois
paramètres
 sock : le socket initialisé
 &sin : adresse de structure SOCKADDR_IN
 sizeof(sin) : la taille de l’adresse
BTS IRIS 2
Les sockets
19
Écouter le port (serveur)
int val = listen(sock, 0);
►
écouter le port sur le socket :
 1er argument, sock : socket sur lequel le listen() écoutera
 2nd argument, le BACKLOG : nombre maximum de connections qui
seront écoutées en même temps
 retourne 0, ou SOCKET_ERROR en cas de problème
généralement utilisé après les appels socket et bind et
juste avant accept
► Ne s’utilise qu’en mode connecté
►
►
L’argument backlog spécifie le nombre de connections à
établir dans une file d’attente par le système lorsque le
serveur exécute l’appel accept
BTS IRIS 2
Les sockets
20
Accepter une connexion (serveur)
SOCKADDR_IN csin;
int val;
val = accept(sock, (SOCKADDR *)&csin, sizeof(csin))
► permet
d'accepter une connection
 1er argument: le socket (qui est en écoute…)
 2ème argument : SOCKADDR du client connecté
 3ème argument : la taille de l’adresse du client
 retourne un identificateur du socket de réponse, ou
INVALID_SOCKET en cas d’erreur
BTS IRIS 2
Les sockets
21
Demander une connexion (client)
int s;
s = connect(sock, (SOCKADDR *)&ssin, sizeof(ssin))
► permet




d'établir une connexion avec un serveur
1er argument : le socket
2ème argument : adresse de l'hôte à contacter
3ème argument : taille de l'adresse de l'hôte
retourne 0 si la connexion a eu lieu, sinon -1
► Pour
établir une connexion, le client ne nécessite
pas de faire un bind()
BTS IRIS 2
Les sockets
22
Les primitives
d’échanges d’information
BTS IRIS 2
Les sockets
23
Émission d’information
► Une
fois que le programme d’application
dispose d’un socket, il peut l’utiliser afin de
transférer des données
► 5 primitives utilisables :





BTS IRIS 2
send
sendto
sendmsg
write
writev
Les sockets
24
Mode connecté
►
send, write et writev ne permettent pas d’indiquer d’adresse de
destination
write ( int sockfd, char *buff, int nbytes ) ;
writev ( int sockfd, iovec *vect_E/S, int lgr_vect_E/S ) ;
int send (int sockfd, char *buff, int nbytes, int flags ) ;
►
►
►
►
►
sockfd : descripteur de socket
buff : pointeur sur un tampon où sont stockées les données à
envoyer
nbytes : nombre d’octets ou de caractères que l’on désire envoyer
vect_E/S : pointeur vers un tableau de pointeurs sur des blocs qui
constituent le message à envoyer
flags : drapeau de contrôle de la transmission
BTS IRIS 2
Les sockets
25
Mode non-connecté
►
sendto et sendmsg imposent d’indiquer l’adresse de destination
int sendto (int sockfd, char *buff, int nbytes, int flags,
struct sockaddr *to, int addrlen) ;
► 4 premiers arguments : mêmes que pour send
► 2 derniers arguments : adresse de destination et sa taille
int sendmsg ( int sockfd, struct struct_mesg, int flags ) ;
► on utilise la structure :
struct struct_mesg
{
int *sockaddr ;
int sockaddr_len ;
iovec *vecteur_E/S
int vecteur_E/S_len
int *droit_dacces
int droit_dacces_len
}
►
Pour les cas où l’appel sendto fréquemment utilisé, on utilise également cette structure
BTS IRIS 2
Les sockets
26
Réception d’information
►5
primitives de réception d’information
symétriques aux appels d’envoi :





BTS IRIS 2
read
readv
recv
recvfrom
recvmsg
Les sockets
27
Mode connecté
int read ( int sockfd, char *buff, int nbytes ) ;
int recv (int sockfd, char *buff, int nbytes, int flags ) ;
►
►
►
►
sockfd : descripteur du socket sur lequel les données seront lues
buff : pointeur sur un buffer où seront stockées les données lues
nbytes : nombre maximal d’octets ou de caractères qui seront lus
flags : drapeau de contrôle de la transmission
int readv ( int sockfd, iovec *vect_E/S, int lgr_vect_E/S ) ;
►
►
►
readv permet de mettre les données lues dans des cases mémoire
non contiguës
Ces cases mémoires sont pointées par un tableau de pointeurs qui lui
même est pointé par vect_E/S
lgr_vect_E/S est la longueur de ce tableau
BTS IRIS 2
Les sockets
28
Mode non-connecté
► il
faut préciser les adresses des correspondants
desquels on attend des données
int recvfrom (int sockfd, char *buff, int nbytes,
int flags, struct sockaddr *from, int addrlen) ;
► Symétrique
de sendto
int recvmsg (int sockfd, struct struct_mesg, int flags);
► Symétrique
de sendmsg
► utilise la même structure struct_mesg
BTS IRIS 2
Les sockets
29
Les ports réservés Unix
►
►
►
►
►
►
►
►
►
►
►
►
►
►
►
►
►
echo
echo
systat
daytime
daytime
netstat
ftp-data
ftp
telnet
smtp
time
time
name
whois
domain
domain
hostnames
BTS IRIS 2
7 (tcp)
7 (udp)
11 (tcp users)
13 (tcp)
13 (udp)
15 (tcp)
20 (tcp)
21 (tcp)
23 (tcp)
25 (tcp mail)
37 (tcp timserver)
37 (udp timserver)
42 (udp nameserver)
43 (tcp nicname)
53 (udp)
53 (tcp)
101 (tcp hostname)
Les sockets
30
BTS IRIS 2
Les sockets
31
BTS IRIS 2
Les sockets
32
Exemple :
serveur « Hello World ! »
BTS IRIS 2
Les sockets
33
Fichiers d’en-tête et bibliothèques
► Windows
:
#include <stdio.h>
#include "winsock2.h"
► Unix
:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
BTS IRIS 2
Les sockets
34
Serveur
void main()
{
WSADATA WSAData;
WSAStartup(MAKEWORD(2,0), &WSAData);
SOCKET sock, SOCKET csock;
SOCKADDR_IN sin, SOCKADDR_IN csin;
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_family = AF_INET;
sin.sin_port = htons(5500);
if(bind(sock, (SOCKADDR *)&sin, sizeof(sin)) < 0)
cout<<"error bind";
else
cout<<"bind ok";
if(listen(sock, 0)<0)
cout<<"erreur de listen";
else
cout<<"listen ok";
while(true)
{
int sinsize = sizeof(csin);
if((csock = accept(sock, (SOCKADDR *)&csin, &sinsize)) != INVALID_SOCKET)
{
if(send(csock, "yes!", 4, 0)<0)
cout<<"error send";
else
cout<<"send ok !";
}
}
}
BTS IRIS 2
Les sockets
35
Client
void main()
{
WSADATA WSAData;
WSAStartup(MAKEWORD(2,0), &WSAData);
SOCKET sock;
SOCKADDR_IN sin;
char *buffer = new char[255];
//configuration en local TCP/IP
if(sock = socket(AF_INET, SOCK_STREAM, 0) < 0)
cout<<"error sock";
else
cout<<"sock ok!"<<endl;
sin.sin_addr.s_addr = inet_addr("127.0.0.1");//mettre l'adrese IP du
serveur
sin.sin_family = AF_INET;
sin.sin_port = htons(5500);//mettre le port correspondant
if(connect(sock, (SOCKADDR *)&sin, sizeof(sin))<0)
cout<<"error connect";
recv(sock, buffer, sizeof(buffer), 0);
string stringBuffer(buffer,sizeof(buffer));
cout << stringBuffer << endl;
closesocket(sock);
WSACleanup();
}
BTS IRIS 2
Les sockets
36
Différents types de serveurs
Tant qu’il n’y a pas de connexions le serveur se bloque sur
cette appel
► Lorsqu’une demande de connexion arrive, l’appel accept
se termine
► Le serveur peut gérer les demandes de 2 manières :
►
 Itérativement : le serveur traite lui même la requête, ferme le
nouveau socket puis invoque de nouveau accept pour obtenir la
demande suivante
 Simultanément : lorsque l’appel accept se termine, le serveur
crée un serveur fils chargé de traiter la demande (appel de fork et
exec). Lorsque le fils a terminer il ferme le socket et meurt. Le
serveur maître ferme quand à lui la copie du nouveau socket après
avoir exécuté le fork. Il appel ensuite de nouveau accept pour
obtenir la demande suivante.
BTS IRIS 2
Les sockets
37
Exemple de serveur itératif
int sockfd, newsockfd ;
if ( ( sockfd = socket (.....)) < 0 )
err_sys(« erreur de socket ») ;
if ( bind ( sockfd, ....) < 0 )
err_sys (« erreur de bind »)
if ( listen ( sockfd , 5) < 0 ) ;
err_sys (« erreur de listen » ) ;
for ( ; ; )
{
newsockfd = accept ( sockfd, .....) ;
if ( newsockfd < 0)
err_sys( « erreur de accept ») ;
execute_la_demande( newsockfd ) ;
close ( newsockfd ) ;
}
BTS IRIS 2
Les sockets
38
Exemple de serveur à accès
concurrent
int sockfd, newsockfd ;
if ( ( sockfd = socket (.....)) < 0 )
err_sys(« erreur de socket ») ;
if ( bind ( sockfd, ....) < 0 )
err_sys (« erreur de bind »)
if ( listen ( sockfd , 5) < 0 ) ;
err_sys (« erreur de listen » ) ;
for ( ; ; )
{
newsockfd = accept ( sockfd, .....) ;
if ( newsockfd < 0)
err_sys( « erreur de accept ») ;
if ( fork() == 0 )
{
close ( sockfd ) ;
execute_la_demande( newsockfd ) ;
exit (1) ;
}
close ( newsockfd ) ;
}
BTS IRIS 2
Les sockets
39