Documente Academic
Documente Profesional
Documente Cultură
Sommaire
Linterface socket 2
Pr-requis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Dfinition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Manuel du pogrammeur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Modle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Couche Transport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Numro de ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Caractristiques des sockets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Manipulations 5
Objectifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
tape n1 : cration de la socket (ct client) . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
tape n2 : attachement local de la socket . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
tape n3 : communication avec le serveur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
tape n4 : vrification du bon fonctionnement de lchange . . . . . . . . . . . . . . . . . . . 12
tape n4 : ralisation dun serveur UDP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Bilan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Questions de rvision 17
Travail demand 17
Exercice 1 : client UDP amlior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Exercice 2 : serveur UDP amlior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Exercice 3 : une messagerie instantane en UDP . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1
LINTERFACE SOCKET
Linterface socket
Pr-requis
La mise en oeuvre de linterface socket ncessite de connatre :
Larchitecture client/serveur
Ladressage IP et les numros de port
Notions dAPI (appels systmes sous Unix) et de programmation en langage C
Les protocoles TCP et UDP, les modes connect et non connect
Dfinition
La notion de socket a t introduite dans les distributions de Berkeley (un fameux
systme de type UNIX, dont beaucoup de distributions actuelles utilisent des morceaux
de code), cest la raison pour laquelle on parle parfois de sockets BSD (Berkeley Software
Distribution).
Il sagit dun modle permettant la communication inter processus (IPC - Inter Process Communication)
afin de permettre divers processus de communiquer aussi bien sur une mme machine qu travers un
rseau TCP/IP. [Wikipedia]
Manuel du pogrammeur
Le dveloppeur utilisera donc concrtement une interface pour programmer une application TCP/IP
grce par exemple :
lAPI Socket BSD sous Unix/Linux ou
lAPI WinSocket sous Microsoft Windows
Les pages man principales sous Unix/Linux concernant la programmation rseau sont regroupes dans le
chapitre 7 :
socket(7) : interface de programmation des sockets
packet(7) : interface par paquet au niveau priphrique
raw(7) : sockets brutes (raw) IPv4 sous Linux
ip(7) : implmentation Linux du protocole IPv4
udp(7) : protocole UDP pour IPv4
tcp(7) : protocole TCP
L'accs aux pages man se fera donc avec la commande man, par exemple : man 7 socket
Modle
Rappel : une socket est un point de communication par lequel un processus peut mettre et recevoir des
donnes.
Ce point de communication devra tre reli une adresse IP et un numro de port dans le cas des
protocoles Internet.
Une socket est communment reprsente comme un point dentre initial au niveau TRANSPORT du
modle couches DoD dans la pile de protocole.
Couche Transport
Rappel : la couche Transport est responsable du transport des messages complets de bout en bout (soit
de processus processus) au travers du rseau.
En programmation, si on utilise comme point dentre initial le niveau TRANSPORT, il faudra alors
choisir un des deux protocoles de cette couche :
TCP (Transmission Control Protocol) est un protocole de transport fiable, en mode connect (RFC
793).
UDP (User Datagram Protocol) est un protocole souvent dcrit comme tant non-fiable, en mode
non-connect (RFC 768), mais plus rapide que TCP.
Numro de ports
Rappel : un numro de port sert identifier un processus (lapplication) en cours de communication
par lintermdiaire de son protocole de couche application (associ au service utilis, exemple : 80 pour
HTTP).
Pour chaque port, un numro lui est attribu (cod sur 16 bits), ce qui implique qu'il existe un maximum
de 65 536 ports (216 ) par machine et par protocoles TCP et UDP.
Lattribution des ports est faite par le systme dexploitation, sur demande dune application. Ici, il faut
distinguer les deux situations suivantes :
cas dun processus client : le numro de port utilis par le client sera envoy au processus serveur.
Dans ce cas, le processus client peut demander ce que le systme dexploitation lui attribue nimporte
quel port, condition quil ne soit pas dj attribu.
cas dun processus serveur : le numro de port utilis par le serveur doit tre connu du processus client.
Dans ce cas, le processus serveur doit demander un numro de port prcis au systme dexploitation
qui vrifiera seulement si ce numro nest pas dj attribu.
Une liste des ports dits rservs est disponible dans le chier /etc/services sous Unix/Linux.
Une socket appartient une famille. Il existe plusieurs types de sockets. Chaque famille possde son
adressage.
Manipulations
Objectifs
Lobjectif de cette partie est la mise en oeuvre dune communication client/serveur en utilisant une
socket UDP sous Unix/Linux.
NOM
socket - Crer un point de communication
SYNOPSIS
#include <sys/types.h> /* Voir NOTES */
#include <sys/socket.h>
DESCRIPTION
socket() cre un point de communication, et renvoie un descripteur.
...
VALEUR RENVOYE
Cet appel systme renvoie un descripteur rfrenant la socket cre sil russit.
Sil choue, il renvoie -1 et errno contient le code derreur.
...
Extrait de la page man de lappel systme socket
laide dun diteur de texte (vi, vim, emacs, kwrite, kate, gedit, ... sous Linux), tapez ( la main, pas
de copier/coller, histoire de bien mmoriser !) le programme suivant dans un fichier que vous nommerez
"clientUDP-1.c" :
#include <stdio.h>
#include <stdlib.h> /* pour exit */
#include <sys/types.h>
#include <sys/socket.h>
int main()
{
int descripteurSocket;
return 0;
}
Un client UDP en C (itration 1)
Pour le paramtre protocol, on a utilis la valeur 0 (voir commentaire). On aurait pu prciser le protocole
UDP de la manire suivante : IPPROTO_UDP.
Un change en UDP
On va tout dabord attacher cette socket une interface et un numro de port local de sa machine en
utilisant utiliser lappel systme bind(). Cela revient crer un point de rencontre local pour le
client. On consulte la page du manuel associe cet appel :
$ man 2 bind
NOM
bind - Fournir un nom une socket
SYNOPSIS
#include <sys/types.h> /* Voir NOTES */
#include <sys/socket.h>
DESCRIPTION
Quand une socket est cre avec lappel systme socket(2), elle existe dans lespace
des noms mais na pas de nom assign). bind() affecte ladresse spcifie dans addr
la socket rfrence par le descripteur de fichier sockfd. addrlen indique la taille,
en octets, de la structure dadresse pointe par addr. Traditionnellement cette
opration est appele affectation dun nom une socket .
VALEUR RENVOYE
Lappel renvoie 0 sil russit, ou -1 sil choue, auquel cas errno contient le code
derreur.
...
Extrait de la page man de lappel systme bind
On rappelle que ladressage dun processus (local ou distant) dpend du domaine de communication
(cad la famille de protocole employe). Ici, nous avons choisi le domaine PF_INET pour les protocoles
Internet IPv4.
Dans cette famille, un processus sera identifi par :
une adresse IPv4
un numro de port
Rappel : linterface socket propose une structure dadresse gnrique sockaddr et le domaine PF_INET
utilise une structure compatible sockaddr_in.
Il suffit donc dinitialiser une structure sockaddr_in avec les informations locales du client (adresse
IPv4 et numro de port).
Pour crire ces informations dans la structure dadresse, il nous faudra utiliser :
htonl() pour convertir une adresse IP (sur 32 bits) depuis lordre des octets de lhte vers celui du
rseau
htons() pour convertir le numro de port (sur 16 bits) depuis lordre des octets de lhte vers celui du
rseau.
Normalement, il faudrait indiquer un numro de port utilis par le client pour cette socket. Cela peut
s'avrer dlicat si on ne connat pas les numros de port libres. Le plus simple est de laisser le systme
d'exploitation choisir en indiquant la valeur 0 dans le champ sin_port.
int main()
{
int descripteurSocket;
struct sockaddr_in pointDeRencontreLocal;
socklen_t longueurAdresse;
Normalement les octets envoys ou reus respectent un protocole de couche APPLICATION. Ici, pour
les tests, notre couche APPLICATION sera vide ! C'est--dire que les donnes envoyes et reues ne
respecteront aucun protocole et ce seront de simples caractres ASCII.
Les fonctions dchanges de donnes sur une socket UDP sont recvfrom() et sendto() qui permettent
la rception et lenvoi doctets sur un descripteur de socket en mode non-connect.
Les appels recvfrom() et sendto() sont spciques aux sockets en mode non-connect. Ils utiliseront
en argument une structure sockaddr_in pour PF_INET.
Ici, on limitera notre client lenvoi dune chane de caractres. Pour cela, on va utiliser lappel sendto() :
$ man 2 sendto
NOM
sendto - Envoyer un message sur une socket
SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>
DESCRIPTION
Lappel systme sendto() permet de transmettre un message
destination dune autre socket.
VALEUR RENVOYE
Sils russissent, ces appels systme renvoient le nombre de caractres mis. Sils
chouent, ils renvoient -1 et errno contient le code derreur.
...
Extrait de la page man de lappel systme sendto
On rappelle que ladressage du processus distant dpend du domaine de communication (cad la famille
de protocole employe). Ici, nous avons choisi le domaine PF_INET pour les protocoles Internet IPv4.
Dans cette famille, un processus sera identifi par :
une adresse IPv4
un numro de port
Et il suffira donc dinitialiser une structure sockaddr_in avec les informations distantes du serveur
(adresse IPv4 et numro de port). Cela revient adresser le point de rencontre distant qui sera utilis
dans lappel sendto() par le client.
Pour crire ces informations dans la structure dadresse, il nous faudra utiliser :
inet_aton() pour convertir une adresse IP depuis la notation IPv4 dcimale pointe vers une forme
binaire (dans lordre doctet du rseau)
htons() pour convertir le numro de port (sur 16 bits) depuis lordre des octets de lhte vers celui du
rseau.
L'ordre des octets du rseau est en fait big-endian. Il est donc plus prudent d'appeler des fonctions qui
respectent cet ordre pour coder des informations dans les en-ttes des protocoles rseaux.
int main()
{
int descripteurSocket;
struct sockaddr_in pointDeRencontreLocal;
struct sockaddr_in pointDeRencontreDistant;
socklen_t longueurAdresse;
char messageEnvoi[LG_MESSAGE]; /* le message de la couche Application ! */
int ecrits; /* nb doctets ecrits */
int retour;
// Initialise 0 le message
memset(messageEnvoi, 0x00, LG_MESSAGE*sizeof(char));
return 0;
}
Un client UDP en C (itration 3)
Le message a t envoy au serveur : ceci peut sexpliquer tout simplement parce que nous sommes en
mode non-connect.
Le protocole UDP ne prend pas en charge un mode able : ici, le client a envoy des donnes sans savoir
si un serveur tait prt les recevoir !
Puis :
$ ./clientUDP-3
Socket cre avec succs ! (3)
Socket attache avec succs !
Message Hello world !
envoy avec succs (14 octets)
Dans l'architecture client/serveur, on rappelle que c'est le client qui a l'initiative de l'change. Il faut donc
que le serveur soit en attente avant que le client envoie ses donnes.
Il est ici possible de prciser avec INADDR_ANY que toutes les interfaces locales du serveur accepteront les
changes des clients.
Dans notre exemple, le serveur va seulement rceptionner un datagramme en provenance du client. Pour
cela, il va utiliser lappel systme recvfrom() :
$ man 2 recvfrom
NOM
recvfrom - Recevoir un message sur une socket
SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>
DESCRIPTION
Lappel systme recvfrom() est utilis pour recevoir des messages.
C'est l'appel recvfrom() qui remplit la structure sockaddr_in avec les informations du point de com-
munication du client (adresse IPv4 et numro de port pour PF_INET).
int main()
{
int descripteurSocket;
struct sockaddr_in pointDeRencontreLocal;
struct sockaddr_in pointDeRencontreDistant;
socklen_t longueurAdresse;
char messageRecu[LG_MESSAGE]; /* le message de la couche Application ! */
int lus; /* nb doctets lus */
int retour;
longueurAdresse = sizeof(pointDeRencontreDistant);
// Initialise 0 la structure sockaddr_in (cest lappel recvfrom qui remplira cette
structure)
memset(&pointDeRencontreDistant, 0x00, longueurAdresse);
// Initialise 0 le message
memset(messageRecu, 0x00, LG_MESSAGE*sizeof(char));
return 0;
}
Un serveur UDP en C
Attention, tout de mme de bien comprendre quun numro de port identifie un processus communiquant !
Excutons deux fois le mme serveur et on obtient alors :
$ ./serveurUDP & ./serveurUDP
Socket cre avec succs ! (3)
Socket attache avec succs !
Socket cre avec succs ! (3)
bind: Address already in use
Explication : l'attachement local au numro de port 5000 du deuxime processus choue car ce numro
de port est dj attribu par le systme d'exploitation au premier processus serveur. TCP et UDP ne
partagent pas le mme espace d'adressage (numro de port logique indpendant).
$ ./clientUDP-3
Socket cre avec succs ! (3)
Socket attache avec succs !
Message Hello world !
envoy avec succs (14 octets)
Il est videmment possible de tester notre serveur avec le client UDP de netcat avec l'option -u.
Bilan
Lchange entre un client et un serveur UDP peut tre maintenant schmatis de la manire suivante :
Questions de rvision
Lide de base des questions de rvision est de vous donner une chance de voir si vous avez identifi et
compris les points cls de ce TP.
Question 3. Quelles sont les deux informations qui dfinissent un point de communication en IPv4 ?
Question 6. quelle couche du modle DoD est relie linterface de programmation socket ?
Question 7. Quel protocole de niveau Transport permet dtablir une communication en mode connect ?
Question 8. Quel protocole de niveau Transport permet dtablir une communication en mode non-
connect ?
Question 10. quels protocoles correspond le domaine PF_INET ? Est-ce le seul utilisable avec linterface
socket ? En citer au moins un autre.
Travail demand
Rappel : rcuprer l'adresse IPv4 en notation dcimale pointe ne pose pas de problme. Par contre, il
vous faudra convertir (avec atoi ou strtol) le numro de port reu sous la forme d'une chane de
caractres en un entier court sur 16 bits avant de l'utiliser.
Rappel : le numro de port du client a t choisi librement (parmi les numros disponibles) par le systme
d'exploitation.
Fonctionnement du mini-chat
Le principe est simple : tous les messages envoys au serveur seront distribus lensemble des clients en
ligne. Un client est considr "en ligne" si il a dj envoy un message.
On se limitera :
des messages dune taille de 225 caractres (pour un tampon de 256 cractres max.)
10 clients en ligne maximum
Un protocole plus labor devrait tre mis en oeuvre au niveau de la couche APPLICATION !
Message : salut !
-> reu du client [192.168.52.3:35256]
Message : ??
-> reu du client [192.168.52.2:54524]
Message : ??
-> envoy [192.168.52.3:35256]
Le client ralis l'exercice 1 peut tre utilis ici. Sinon, vous pouvez faire vos tests avec netcat.
$ nc -u 192.168.52.83 5000
??
[192.168.52.1:35639]> Bonjour tous !
[192.168.52.3:35256]> Il y a du monde aujourdhui ;)
Le client 192.168.52.2
$ nc -u 192.168.52.83 5000
Bonjour tous !
[192.168.52.3:35256]> Il y a du monde aujourdhui ;)
Le client 192.168.52.1