Vous êtes sur la page 1sur 11

Sockets (prises)

!! Les sockets permettent la communication entre processus situés


Les sockets !!
!!
sur une même machine (domaine AF_UNIX)
ou sur des machines différentes (domaine AF_INET).
!! Socket est un point d'une communication :
!! envoi: un message est envoyé vers une socket
!! réception: un message est reçu sur une socket
!! Deux modes de communication
!! mode non connecté (sans connexion)
"! messages (ou datagrammes)
"! transport non fiable
!! mode connecté (avec connexion)
"! séquences de caractères (flot d’octets ou stream)
"! transport fiable
"! ordre FIFO

Insertion dans l’environnement Désignation (ou nommage)


4 5

!! Pour chaque socket le système gère la structure de données


nécessaire à la communication (tampon + indices dans tampon + …)

!! Désignation d'une socket:


!! Désignation (ou adresse) interne : indice dans la table des descripteurs de
fichiers du processus
!! Désignation (ou addresse) externe : adresse machine + numéro de port
Place des sockets TCP vs UDP
7 8

!! Les sockets fournissent une interface TCP UDP


d’accès, à partir d’un hôte, aux !! Communication par flots !! Communication par
interfaces de transport TCP et UDP datagrammes
d’octets
!! TCP (mode connecté) : !! Transmission non fiable
!! Transmission fiable
!! une liaison est établie au préalable "! il n'y a pas de garantie de bonne
entre deux hôtes, "! Fiabilitégarantie dès lors que livraison d'un datagramme à sa
!! ensuite les messages (plus exactement
la liaison physique existe destination
des flots d’octets) sont échangés sur !! Transmission ordonnée !! Transmission non ordonnée
cette liaison "! Ordre de réception identique "! l'ordre d'arrivée des datagrammes
!! UDP (mode non connecté) : à l’ordre d’émission peut différer de l'ordre d'envoi
aucune liaison n’est établie !! Les fonctions assurant la
!! !! Contrôle de flux
Les messages sont échangés retransmission et le ré-
!! "! Permet au récepteur de limiter ordonnancement doivent être
individuellement le débit d’émission en fonction assurées par les protocoles de la
de ses capacités de réception couche supérieure si elles sont
souhaitées.

Principes de base Définition des sockets


9 10

1.! Chaque machine crée une socket,


2.! Chaque socket sera associée à un port de sa machine
hôte,
3.! Les deux sockets seront explicitement connectées si on
utilise un protocole en mode connecté …, !! Familles de sockets :
!! processus sur la même station Unix :
4.! Chaque machine lit et/ou écrit dans sa socket, "! sockets locales (AF_UNIX)
5.! Les données vont d’une socket à une autre à travers le !! processus sur des stations différentes à travers Internet :
réseau, "! sockets Internet (AF_INET)
6.! Une fois terminé chaque machine ferme sa socket. !! Modes de communication :
!! Datagrames – ou mode non connecté (SOCK_DGRAM)
!! Flôt de données – ou mode connecté (SOCK_STREAM)
!! Protocoles de sockets : IP, UDP, TCP, …
Format de présentation en mémoire
Ordre des bits
Conversion des nombres
11 12

!! Les données ne sont pas représentées de la même façon par !! htons() : host to network short (2 octets)
tous les processeurs (host byte order ou ordre des octets de !! convertitun entier court (short) depuis l'ordre des octets de
l’hote) l'hôte (Host byte order) vers celui du réseau (Network byte
!! Big Endian : bit de poids fort à gauche order).
!! Little Endian : bit de poids fort à droite !! htonl() : host to network long (4 octets)
!! Expression des @ des machines et des numéros de ports : !! convertit un entier long depuis l'ordre des octets de l'hôte
!! Une communication met en jeu 2 machines identifiées par vers celui du réseau
@machine et #port !! ntohs() : network to host short
!! Les deux machines peuvent avoir des codages différent des !! convertitun entier court depuis l'ordre des octets du réseau
nombres vers celui de l'hôte
!! Pour remédier à ce problème, le protocole IP définit un !! ntohl() : network to host long
standard, le network byte order (ordre des octets du réseau) !! convertit un entier long depuis l'ordre des octets du réseau
# Big Endian vers celui de l'hôte

Conversion des @IP La fonction gethostbyname


13 14

!! in_addr inet_addr (const char *cp); !! Utiliser les DNS (Domain Name Services) pour éviter la manipulation des
!! convertit l'adresse Internet de l'hôte cp depuis la notation standard @IP (www.google.com $% 216.239.39.99)
avec nombres et points en une donnée binaire dans l'ordre des octets !! La fonction gethostbyname renvoie une structure de données (hostent) en
du réseau interrogeant le serveur DNS avec le nom de l’hôte (name)
!! si l'adresse est invalide, -1 est renvoyé
struct hostent * gethostbyname (const char * name);
!! char * inet_ntoa (struct in_addr in);
!! convertit l'adresse Internet de l'hôte in donnée dans l'ordre des octets
du réseau en une chaîne de caractères dans la notation avec h_name : nom officiel de l'hôte
struct hostent { char *h_name;
nombres et points char **h_aliases; h_aliases : table d'alternatives au nom
int h_addrtype;
officiel de l'hôte
!! Le numéro fictif INADDR_ANY signifie que la socket peut-être int h_length; h_addrtype : type d'adresse (AF_INET)
associée à n'importe quelle adresse IP de la machine locale (s'il en char **h_addr_list; h_length : longueur, en octets, de l’@
existe plusieurs). } h_addr_list : table d’@ réseau pour l'hôte,
#define h_addr h_addr_list[0] avec l'ordre des octets du réseau
h_addr : première @ dans h_addr_list
Programmation des sockets Adresse générique d’une socket
15 16

!! Plusieurs langages possibles :


!! C, C++, Java, JavaScript, PHP, … struct sockaddr {
unsigned short sa_family;
!! Plusieurs systèmes d’exploitation
unsigned char sa_data[14];
!! Windows, Linux, MacOS,… };

!! Une structure générique qui permet d'utiliser n'importe quelle couche


réseau (IP, IPSec, AppleTalk,...)
Dans la suite, on traite les sockets uniquement !! sa_family : contient le type d’adresse : AF_INET ou AF_UNIX
en langage C avec le système d’exploitation Linux !! sa_data : contient l’adresse de destination et le numéro de port
!! Il existe également une autre structure faite pour contenir les
informations IP, c'est cette structure là que l'on va utiliser.

Adresse Internet d’une socket socket : définition de socket


17 18

!! sockaddr_in : !! Création d'une socket = allocation de la structure de données:


!! adresse Internet int socket (int domaine, int type, int protocole)
struct in_addr { !! Plus spécialisée que sockaddr
!! Même taille que sockaddr
unsigned long s_addr; domaine:
!! sin_family : !!
}; !! AF_UNIX ou AF_INET !! AF_UNIX : pour communication locale (même machine)
!! sin_port : !! AF_INET : réseau internet
struct sockaddr_in { !! le numéro de port
!! type:
!! sin_addr :
unsigned short sin_family; !! SOCK_STREAM : mode connecté, communication fiable, TCP
!! une structure de type addr_in qui servira à
unsigned short sin_port; contenir l'adresse IP destination !! SOCK_DGRAM : mode non connecté, communication non fiable, UDP
struct in_addr sin_addr; !! sin_zero : !! protocole: la valeur 0 emploie le protocole par défaut selon le type
une suite des zero
char sin_zero[8];
!!
!! l'appel retourne
!! Nécessaire pour que la taille de la structure
}; sockaddr_in soit la même que celle de !! un descripteur de socket ( = indice dans la table des descripteurs de
sockaddr. fichiers du processus)
!! L’affectation des zeros doit être réalisée avec la !! ou -1 (en cas d’échec).
fonction memset()
bind : attribution d'une adresse externe close : fermeture d’une socket
19 20

!! Après sa création, une socket n'a pas d'adresse externe; !! pour fermer la socket :
!! une adresse externe est attribuée grâce à la fonction bind
int close (int sockfd)
int bind (int sockfd, struct sockaddr * my_addr, int addr_len)

!! sockfd:
descripteur de socket !! sockfd: descripteur de socket.
!! my_addr: pointeur sur une structure sockaddr qui contient
"! adresse machine locale (adresse IP)
"! numéro de port
!! addr_len: longueur de la structure my_addr

Communication en mode déconnecté (UDP) Communication en mode déconnecté (UDP)


21 22

!! le serveur et le client ouvrent chacun une « socket »


!! le serveur la nomme (il l’attache à un de ses ports (un port !! socket() : création d’une socket
précis))
!! le client ne nomme pas sa socket (elle sera attachée !! bind() : attache la socket à une
automatiquement à un port lors de l’émission) adresse externe (@ et #Port)
!! le client et le serveur dialogue : sendto(…) et recvfrom(…)
!! finalement toutes les sockets doivent être refermées !! sendto() : envoi d'un message

!! Les deux extrémités n’établissent pas une connexion : !! recvfrom() : réception du message
!! elles ne mettent pas en œuvre un protocole de maintien de
connexion
!! si le processus d’une extrémité meurt l’autre n’en sait rien ! !! close() : fermeture de la socket
Communication en mode déconnecté (UDP) sendto : envoi en mode datagrammes (UDP)
23 24

int sendto ( int sockfd, void *buf, int long, int option,
struct sockaddr *dst, int lg_addr )

!! sockfd: descripteur de socket de l'émetteur;


!! buf: adresse du buffer contenant le message à envoyer;
!! long: longueur du message à envoyer;
!! dst: adresse externe de la socket du destinataire (machine,
port);
!! si sockfd n'est pas lié à un port local (fonction bind), ceci est
fait automatiquement par l'appel sendto (le numéro de port
est choisi parmi les ports libres);
!! option 0 pour DGRAM
!! retourne le nombre d’octets effectivement envoyés

Serveur UDP
recvfrom : réception en mode datagrammes (UDP) (Squelette)

25

int recvfrom (int sockfd, void * buf, int long, int option,
struct sockaddr *exp, int * lg_addr)

!! sockfd: descripteur de socket du récepteur


!! buf: buffer pour stocker le message reçu Création de socket
!! long: taille du buffer
Création de l’@
!! exp: adresse externe de l'expéditeur (machine, port), pour externe de socket
l'envoi d'une éventuelle réponse
!! l'appel retourne la longueur du message reçu Attachement de socket

!! ne permet de recevoir qu’un seul message: exactement un Réception de msg


message est extrait du tampon de réception. S’il est plus
long que l’espace alloué par le récepteur, il est tronqué et
le reste du message est perdu. Envoi de msg
Fermeture de socket
Client UDP
(Squelette) Communication en mode connecté (TCP)
31

!! 2 phases:
!! établissement de la connexion,
!! puis communication
!! Echange bidirectionnel fiable de séquences d'octets (ordre
FIFO)
Création de socket !! Une fois la connexion établie: P1 désigne pour envoyer et
recevoir; P2 désigne pour envoyer et recevoir
Création de l’@
externe de socket
serveur

Envoi de msg

Réception de msg

Fermeture de socket

Communication en mode connecté (TCP) Communication en mode connecté (TCP)


32 33

!! Etapes d’une connexion client-serveur en TCP :


!! socket() : création d' un socket
!! le serveur et le client ouvrent chacun une « socket »
!! le serveur la nomme (il l’attache à un de ses ports (un port précis)) !! bind() : attache la socket à une
!! le client n’est pas obligé de la nommer (elle sera attachée adresse externe (@ et #Port)
automatiquement à un port lors de la connexion)
!! le serveur écoute sa socket nommée !! listen() : écoute de connexions
"! le serveur attend des demandes de connexion
"! le client connecte sa socket au serveur et à un de ses ports (précis) !! connect() : demande une
connexion
!! le serveur détecte la demande de connexion
"! une nouvelle socket est ouverte automatiquement !! accept() : accepte la connexion
!! le serveur crée un processus pour dialoguer avec le client
"! le nouveau processus continue le dialogue sur la nouvelle socket !! send() : envoi de données
!! le serveur peut attendre en parallèle de nouvelles demandes de
connexions !! recv() : réception des données
!! finalement toutes les sockets doivent être refermées
!! close() : fermeture de la socket
Communication en mode connecté (TCP) Communication en mode connecté (TCP)
34 35

Etapes d’une connexion client-serveur en TCP : Etapes d’une connexion client-serveur en TCP :

Communication en mode connecté (TCP) TCP: établissement de la connexion


36 37

!! Détection de fin de connexion: !! L'établissement de la connexion n'est pas symétrique


!! Protocole de maintien de connexion !! Protocole du client / Protocole du serveur
!! Serveur : se déclare prêt à accepter une connexion en désignant
!! Si le processus d’une extrémité meurt l’autre en est averti 4
!! Si le client meurt la nouvelle socket automatiquement !! Client : demande une connexion en désignant 1 et 3

ouverte sur le serveur est détruite !! Cette demande provoque la création de la socket 5|6, et
connecte 1|2 avec 5|6
Etablissement de connexion: client Client-serveur en mode concurrent
38 39

!! Pour réaliser un serveur en mode concurrent (pour


servir plusieurs clients simultanément):
!! créer un nouveau processus pour servir chaque demande de
connexion
!! le programme principal du serveur ne faisant que la boucle
d’attente sur les demandes de connexion
!! Le processus principal (appelé veilleur) attend sur
accept()
!! Lorsqu’il reçoit une demande de connexion, il crée un
processus fils (appelé exécutant) qui va interagir avec
le client
!! Le veilleur revient se mettre en attente sur accept()
!! Plusieurs exécutants peuvent exister simultanément

Etablissement d'une connexion: serveur Serveur e client en mode TCP


40 41
TCP côté client: connect( ) TCP côté serveur: listen ( )
42 43

!! Demande de connexion (par le client): !! Ouverture du service:

int connect (int sockfd, struct sockaddr *dst_addr, int len); int listen (int sock, int len)

!! sockfd: descripteur de la socket du client !! sock: descripteur de socket


!! dst_addr: pointeur sur la structure sockaddr qui contient !! len: longueur maximale de la queue de demandes de
!! adresseIP de la machine serveur; connexion
!! numéro de port; !! une fois cette limite atteinte, une nouvelle demande de connexion
d'un client échoue
!! len: longueur de la structure dst_addr
!! l'appel retourne 0 en cas de succès, -1 en cas d'erreur
!! l'appel retourne 0 en cas de succès, -1 en cas d'erreur

TCP côté serveur: accept ( ) send/recv: envoi et reception en mode TCP


44 45

!! Attente de demande de connexion: int send ( int sockfd, void *buf, int long, int option)
int accept ( int sockfd, struct sockaddr *client_addr, int *len); !! sockfd: descripteur de socket de l'émetteur;
!! buf: adresse du buffer contenant les données à envoyer;
!! sockfd: descripteur de socket !! long: taille des données à envoyer;
!! client_addr: pointeur sur une structure sockaddr qui contiendra
"! adressemachine du client connecté (adresse IP)
"! numéro de port int recv( int sockfd, void *buf, int long, int option)
!! len:longueur de la structure client_addr !! sockfd: descripteur de socket de récepteur;
!! l'appel retourne le descripteur de la socket créée, ou –1 en !! buf: adresse du buffer contenant les données à recevoir;
cas d'erreur !! long: taille des données à recevoir;
Client TCP Serveur TCP (1/2)

Serveur TCP (2/2)

Pour un serveur concurrent (ou parallèle): cette fonction serait


lancée en tant que tâche disjointe (exécutant) pour chaque client
! permettrait de servir d’autres clients en parallèle (Voir TD)

Vous aimerez peut-être aussi