Vous êtes sur la page 1sur 32

Département Génie Informatique

Protocole WebSocket
Pr. Omar MOUSSAOUI
o.moussaoui@ump.ac.ma

Filière : GIE2, Année 2022-2023


PLAN
Les sockets en mode TCP/UDP
Les sockets en C sous Linux
Protocole HTTP
Protocole WebSocket
Les sockets
▪ Introduit par le système Unix BSD 4.1 en 1981
▪ Un socket est une API entre la couche
application et la couche transport
▪ Une porte permettant aux applications de
recevoir/transmettre des données sur un réseau
▪ Explicitement créé, utilisé et libéré par l’application
▪ Utilisé dans l’architecture Client/Serveur
▪ Deux types de service proposés
▪ Non-fiable (datagramme) ➔ UDP
▪ Fiable (flux ou stream) ➔ TCP
▪ Pour établir une communication vers une
machine distante, il faut
▪ s’attribuer un numéro de port
▪ déterminer l’adresse IP de la machine avec laquelle les
échanges vont s’effectuer
▪ connaître ou déterminer le numéro de port du service
distant
Les sockets
 Utilisation des Sockets en mode connecté (TCP)
 SERVEUR
◼ crée un socket

◼ associe une adresse socket (son adresse IP et le numéro de port choisi) au service

◼ se met à l’écoute des connexions entrantes

◼ Pour chaque connexion entrante


◼ accepte la connexion ➔ un nouveau socket est ainsi créé avec les mêmes
caractéristiques que le socket d’origine
◼ lit ou écrit sur le nouveau socket
◼ ferme le nouveau socket

 CLIENT
◼ crée un socket
◼ se connecte au serveur en donnant l’adresse socket distante (adresse IP du serveur
et numéro de port du service)
◼ Cette condition attribue automatiquement un numéro de port local au client
◼ lit ou écrit sur le socket
◼ ferme le socket
Les sockets
 Utilisation des Sockets en mode connecté (TCP)
 Architecture Client/serveur en mode TCP
Les sockets
Utilisation des Sockets en mode non connecté (UDP)

 Pas d’établissement de connexion


 Pour que le client puisse contacter le
serveur
◼ il doit connaître l'adresse de socket du
serveur
◼ le serveur doit avoir créé le socket de
réception
 Le client envoie sa requête en précisant,
lors de chaque envoi, l'adresse du
socket destinataire
 Le datagramme envoyé par le client
contient l'adresse du socket émettrice
(port, @IP)
 Le serveur traite la requête et répond
au client en utilisant l'adresse du
socket émetteur de la requête
Client/serveur en mode UDP
Les sockets en C sous Linux
 Adressage dans le domaine AF_INET
 Structures définies dans le fichier <netinet/in.h>

struct in_addr {
u_long s_addr;
}

struct sockaddr_in { /* in comme Internet */


short sin_family; /* AF_INET */
u_short sin_port; /* numéro du port en ordre réseau */
struct in_addr sin_addr; /* adresse Internet de la machine en
ordre réseau */
char sin_zero[8]; /* inutilisé */
}
Les sockets en C sous Linux
 Fichier d’inclusion pour AF_INET

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>

 Création d’un socket (TCP ou UDP)


int socket (
int domaine; /* AF_INET ou AF_UNIX */
int type; /* SOCK_STREAM (TCP) ou SOCK_DGRAM (UDP)*/
int protocole; /* IPPROTO_TCP ou IPPROTO_UDP équivalent si = 0*/
);
Les sockets en C sous Linux
 Primitive bind (TCP ou UDP)
 La primitive bind associe une adresse locale (port) à un descripteur de socket. Il est
facultatif pour les clients TCP car il se fait à la connexion.
int bind (
int socket ; /* descripteur du socket */
struct sockaddr *adresse; /*adresse socket (port+adresse) */
int l_adresse; /* longueur de la structure adresse */
);

 Connexion d’un client à un serveur (TCP)


int connect (
int socket; /* descripteur du socket */
struct sockaddr *adresse; /*adresse socket (port+adresse) */
int l_adresse; /* longueur de la structure adresse */
);
NB : Il faut convertir le type sockaddr_in pour le domaine INET en sockaddr
Les sockets en C sous Linux
 Primitives listen (TCP)
 Mise d’un serveur à l’état d’écoute : indique que le serveur peut attendre au
maximum qlen requêtes des clients.
int listen (
int socket; /* descripteur socket */
int qlen; /* nombre maximal de connexions traitées */
);

 Primitive accept (TCP)


 Elle retourne un nouveau descripteur de socket, qui sera utilisé pour l’échange de
données avec le client.

int accept(
int socket; /* descripteur retourné par la primitive socket */
struct sockaddr *adr; /* initialisé à vide et mis à jour par accept avec le port et
l'adresse IP de la machine où se trouve le client qui a
fait un connect */
int l_adresse; /* longueur de la structure adresse*/
);
Les sockets en C sous Linux
 Primitive de réception en mode TCP
 retourne le nombre de caractères effectivement reçus ou -1 en cas d'erreur

ssize_t recv (
int descripteur, /* descripteur du socket*/
void *ptr, /* adresse de réception */
size_t nb_caracteres, /* indique le nombre d'octets à lire*/
int option /* = 0, MSG_PEEK pour consulter sans extraire,
MSG_OOB pour lire une donnée (1 car) urgente */
);

 Primitive d’envoi en mode TCP


 retourne le nombre de caractères effectivement envoyés ou -1 en cas d'erreur

ssize_t send (
int descripteur, /* descripteur du socket*/
void *ptr, /* adresse d’envoi*/
size_t nb_caracteres, /* indique le nombre d'octets à lire*/
int option /* indique le type d'envoi =0 ou MSG_OOB */
);
Les sockets en C sous Linux
 Primitive de réception en mode UDP
 retourne le nombre de caractères effectivement reçus ou -1 en cas d'erreur

int recvfrom(
int descripteur, /* descripteur de la socket */
void * message, /* adresse de réception */
int longueur, /* taille zone réservée */
int option, /* 0 */
struct sockaddr *ptr_adresse, /* adresse émetteur */
int *ptr_longueur_adresse /* pointeur sur longueur zone adresse */
);

 Primitive d’envoi en mode UDP


 retourne le nombre de caractères effectivement envoyés ou -1 en cas d'erreur

int sendto(
int descripteur, /* descripteur de la socket*/
void * message, /* adresse d’envoi*/
int longueur, /* longueur du message*/
int option, /* 0*/
struct sockaddr *ptr_adresse, /* adresse destination*/
int longueur_adresse /*longueur adresse destination*/
);
Les sockets en C sous Linux
 Primitive close (TCP et UDP)
 Le noyau essaie d’envoyer les données non encore émises avant de sortir de close().

int close (
int socket; /* descripteur de socket */
);

 Primitives auxiliaires
 Primitives permettant de convertir le format local (“little indian” ou “big indian”) en
format réseau (toujours “big indian”) ou bien de faire l’opération inverse.

#include <sys/types.h>
#include <netinet/in.h>
u-long htonl (u_long hostlong); /*host to network long*/
u-long ntohl (u_long hostlong); /*network to host long*/
u_short htons (u_short netshort); /*host to net short*/
u_short ntohs (u_short netshort); /*net to host short*/
Les sockets en C sous Linux
 Primitives auxiliaires
 Permet de construire l’adresse IP à partir du nom d’une machine.

#include <netdb.h>
struct hostent *gethostbyname (char *hostname);

Retourne un pointeur sur une structure hostent :


struct hostent {
char *h_name; /* nom de la machine */
char **h_aliases; /* liste d’alias */
int h_addrtype; /* AF_INET */
int h_length; /* 4 octets */
char **h_addr_list; /* liste d’adresses IP, chaque adresse est donnée en
adresse réseau*/
};

#define h_addr h_addr_list[0] // la 1ère adresse


Protocole HTTP
▪ HTTP est un protocole de la couche « Application », couche la plus haute
des modèles OSI ou Internet (TCP/IP).
▪ Il s’agit d’un protocole client-serveur (requête/réponse) :
▪ Un client demande l’accès à une ressource (ça peut être aussi
l’exécution d’un programme) en indiquant entre autres un URL.
▪ Le serveur répond en renvoyant la ressource demandée (ou les
résultats de l’exécution du programme)
▪ Parmi les clients les plus connus : les navigateurs Web et les robots
d’indexation de pages Web
▪ Parmi les serveurs les plus connus : Apache (C), Tomcat (Java), IIS (C# &
ASP.Net) et serveurs écrits avec Node.js (JavaScript)
Protocole HTTP
▪ Toute application Web s’appuie sur HTTP :
▪ Des programmes exécutés par le processus serveur (httpd sous
Unix) produisent des réponses HTTP :
▪ des interfaces utilisateurs (HTML, CSS, ...)
▪ + des programmes (JS) destinés aux « programmes » clients
▪ Les programmes clients (processus du navigateur) :
▪ produisent le rendu graphique de l’interface utilisateur
▪ attendent les actions de l’utilisateur sur cette interface
▪ peuvent envoyer des requêtes HTTP et attendre les réponses
▪ L’interaction entre les programmes se fait toujours selon le modèle
requête/réponse. Elle est toujours initiée par le client
Protocole HTTP
▪ HTTP peut théoriquement fonctionner sur n’importe quel protocole de la
couche transport
▪ En pratique, HTTP utilise TCP, de la façon suivante :
▪ Le client établit une connexion TCP avec le serveur (TCP handshake)
▪ Le client envoie une requête en utilisant cette connexion et attend la
réponse
▪ Le serveur se limite à répondre aux requêtes. Il n’envoie pas de
façon proactive des messages aux clients
▪ HTTP utilise une seule connexion TCP par requête
▪ On a une connexion fiable du client vers le serveur
▪ Mais le serveur ne cherche pas à avoir une connexion fiable avec un
client (le client redemande la ressource si problème)
Protocole HTTP
Problèmes avec le protocole HTTP
▪ HTTP est le protocole standard utilisé pour le Web, il est très efficace pour certains cas
d’utilisation mais il dispose néanmoins de quelques inconvénients dans le cas
d’applications Web interactive :
▪ Half-duplex (Communication bidirectionnelle mais pas en même temps) : basé sur le
principe requête/réponse, le client envoi une requête puis le serveur réalise un
traitement avant de renvoyer une réponse, le client est donc contraint d’attendre une
réponse du serveur.
▪ Verbose (Informations supplémentaires) : beaucoup d’informations sont présentes
avec les headers HTTP associés au message, aussi bien dans la requête HTTP que
dans la réponse HTTP.
▪ Non connecté : son avantage mais également son gros défaut, c'est que ce
protocole HTTP est la plupart du temps en mode non connecté. Lorsque la réponse a
été obtenu à l'issue de la requête proposé par le client, la connexion est
définitivement interrompue jusqu'à ce qu'une nouvelle requête soit proposée. Si vous
désirez que le serveur envoie de lui-même des informations, il est nécessaire
d’utiliser des méthodes de contournement (polling, long polling, Comet/Ajax) car il
n’existe pas de standard.
NB: Ce protocole n’est donc pas optimisé pour des applications qui ont d’important besoins
de communication temps réel bidirectionnelle.
Applications nécessitant un modèle d’interaction différent
▪ Beaucoup d’applications distribuées nécessitent des interactions initiées
par les deux parties (client et serveur) :
▪ Applications multi-utilisateurs : messagerie instantanée, éditeurs
collaboratifs avec édition simultanée, visioconférence, jeux
interactifs, ...
▪ Applications dépendant de données à jour sur le serveur
▪ Le client envoie des requêtes au serveur, mais le serveur envoie aussi
des ressources au client, sans que le client n’en fasse explicitement la
demande (Mode push)
▪ Exemple : Messagerie instantanée (chat) sur le Web
▪ Le serveur gère deux clients à un moment donné
▪ Lorsque le serveur reçoit un message du client 1, comment fait-il
pour transmettre ce message au client 2 ?
HTTP Bidirectionnel

▪ Périodiquement, le client sollicite le serveur pour des mises à jour des


ressources (periodic polling)
▪ Mais cette solution est très consommatrice en ressources (réseau et
serveur, à cause des requêtes inutiles, si fréquence importante du
polling)
▪ Les deux techniques les plus courantes du HTTP bidirectionnel sont :
▪ HTTP Long Polling
▪ HTTP Streaming
HTTP Long Polling

▪ Le client envoie une requête au serveur


▪ Le serveur ne répond pas tout de suite
▪ Il attend que les ressources demandées
aient été mises à jour
▪ Dès qu’il y a une mise à jour (ou un
timeout), le serveur répond au client
▪ Dès la réception de la réponse, le client
envoie une autre requête, et ainsi de suite
HTTP Streaming

▪ Le client envoie une requête au serveur


▪ Le serveur ne répond pas tout de suite
▪ Il attend que les ressources demandées aient
été mises à jour
▪ Le serveur répond au client, mais indique
que c’est une réponse partielle (le reste est
à suivre). La connexion n’est pas terminée
▪ Le client attend la suite jusqu’à ce que le
serveur décide de la fin (ressources
envoyées entièrement)
Limites de HTTP bidirectionnel
▪ Les techniques basées sur le HTTP bidirectionnel fonctionnent mal
ou pas, en présence d’entités intermédiaires, ex. proxies, qui
peuvent utiliser des caches (bufferiser réponses partielles du long
polling)
▪ Manque d’efficacité parce que :
▪ surcoût lié aux multiples messages échangés (messages avec
headers HTTP),
▪ le serveur doit attendre,
▪ des ressources OS sont allouées pour des connexions
TCP/Requêtes HTTP ouvertes dans le long polling, ...
▪ Support faible côté client et aucune obligation à les implémenter
WebSocket: Aperçu du protocole
▪ C’est pourquoi le nouveau protocole WebSocket propose des fonctionnalités plus
évoluées que HTTP, puisqu’il est :
▪ Basé sur une unique connexion TCP entre deux pairs (en HTTP chaque
requête/réponse nécessite une nouvelle connexion TCP).
▪ Bidirectionnel : le client peut envoyer un message au serveur et le serveur peut
envoyer un message au client.
▪ Full-duplex : le client peut envoyer plusieurs messages vers le serveur et le
serveur vers le client sans attendre de réponse l’un de l’autre.
▪ Grâce à ce principe, le protocole WebSocket propose une implémentation native et
unifiée dans les navigateurs et serveurs web d'un canal bidirectionnel permettant en
temps réel :
▪ la notification au client d'un changement d'état du serveur.
▪ l'envoi de données en mode Push du serveur vers le client sans que ce dernier ait
à effectuer une quelconque requête.
NB: Le terme client est utilisé uniquement pour définir celui qui va initialiser la connexion. Dès lors
que la connexion est établie, le client et le serveur deviennent tous les deux des pairs, avec les
mêmes pouvoirs l’un par rapport à l’autre.
WebSocket: Aperçu du protocole
Deux phases interviennent dans ce processus:
▪ Handshake HTTP : Requête HTTP GET upgrade, puis réponse HTTP
▪ Transfert de données TCP : bidirectionnel (chaque cote peut envoyer des données
de façon délibérée)
➔ La fermeture de la connexion se fait par envoi de frames de contrôle

Une interaction WebSocket commence


par un établissement de liaison dans
lequel les deux parties (le client et le
serveur) confirment mutuellement leur
intention de communiquer via une
connexion permanente.
Ensuite, un groupe de paquets de
messages est envoyé via TCP dans les
deux sens.
WebSocket: Handshake
Handshake (Poignée de main) : Requête HTTP GET upgrade, puis réponse HTTP
▪ Cette phase correspond à un unique échange « requête/réponse HTTP » entre
l’initiateur de la connexion «pair client» et le «pair serveur».
▪ La requête est un HTTP GET configuré comme une demande de mise à niveau

▪ Avec HTTP, une requête du client avec l'en-tête Upgrade indique l'intention du
client de demander à ce que le serveur passe à un autre protocole.
▪ Avec le protocole WebSocket, la demande de mise à niveau effectuée au
serveur contient une clé unique que le serveur retournera altérée comme preuve
qu'il a accepté la demande de mise à niveau.
WebSocket: Handshake
Handshake (Poignée de main) : Requête HTTP GET upgrade, puis réponse HTTP
▪ Exemple de réponse à une demande d'établissement de liaison

▪ Le code de statut de réussite est toujours 101. Tout autre code de statut sera
interprété comme un refus de mettre à niveau vers le protocole WebSocket.
▪ Le serveur concatène la clé reçue avec une chaîne GUID fixe et il calcule le
hachage à partir de la chaîne obtenue. La valeur de hachage est ensuite
codée en Base64 et retournée au client via l'en-tête Sec-WebSocket-Accept.
NB: Lorsque la demande de mise à niveau du protocole HTTP vers le protocole Web Socket
a été validée par le serveur « Endpoint », il n’y a plus de communication possible en
HTTP, tous les échanges sont réalisés via le protocole WebSocket.
WebSocket: Transfert de données
▪ Data transfer: Une fois que l'initialisation de la connexion a été faite entre le client et le
serveur, ceux-ci sont connectés et appairés; les deux peuvent envoyer, recevoir des
messages et fermer la connexion.
▪ Une fois que le handshake est acceptée, la mise en place du protocole WebSocket
est donc acquise. Une connexion côté pair serveur est ouverte ainsi que côté pair
client, une gestion de callback est activée pour initier la communication.
▪ La phase de Data transfer peut alors entrer en jeu, c’est-à-dire que les deux pairs
peuvent désormais s'échanger des messages dans une communication
bidirectionnelle et full-duplex.

NB: À la suite de l'établissement de liaison, le client et le serveur peuvent envoyer des


messages librement via le protocole WebSocket. Notez que les messages WebSocket
sont asynchrones et qu'une demande d'envoi ne recevra donc pas nécessairement une
réponse immédiate, comme avec HTTP. Avec le protocole WebSocket, il est conseillé de
réfléchir en termes de messages généraux allant du client vers le serveur, ou
inversement, et d'oublier le modèle classique requête/réponse de HTTP.
WebSocket: Transfert de données
▪ Le protocole WebSocket a été conçu pour être une couche « fine » au
dessus de TCP.
▪ Le protocole WebSocket est indépendant de HTTP, sauf pour le
handshake pour l’instant. Il simplifie la communication client/serveur et le
format d’échange de messages (il est très proche de TCP).
▪ Les données peuvent être transmises par le client ou par le serveur à
n’importe quel moment, tant que la connexion est ouverte.
▪ Le client/serveur peut faire plusieurs envois successifs.
▪ Transfert sous la forme de trames de données textuelles (en UTF-8) ou
binaires.
▪ Une trame de contrôle transmise des deux côtés ferme la connexion
WebSocket (qui sera suivie de la fermeture de la connexion TCP sous-
jacente)
▪ Au delà, aucun transfert de données n’est possible
WebSocket: États d’une connexion

▪ CONNECTING : Le client a envoyé la requête correspondant au


handshake et attend la réponse du serveur
▪ OPEN : Le serveur a répondu avec succès à la requête du client. La
connexion est maintenant établie entre le client et le serveur
▪ CLOSING : L’une des extrémités (endpoints) a demandé la fermeture de
la connexion et attend la confirmation de l’autre extrémité
▪ CLOSED : état final
WebSocket: États d’une connexion

Vous aimerez peut-être aussi