Académique Documents
Professionnel Documents
Culture Documents
Les SOCKETS
1.1Introduction
Le mécanisme des sockets peut être considéré comme héritant à la fois des fonctions de communication entre
processus et des fonctions de lecture et d'écriture dans un fichier :
• Comme pour un fichier, il sera nécessaire d'ouvrir un canal de communication de type "socket", avant de
pouvoir écrire ou lire des données. A la fin de la session de communication, le canal sera fermé
• Mais ces données seront en fait échangées entre un processus serveur et un processus client, qui résideront
en général sur des machines différentes et quelquefois sur la même machine.
Tableau comparatif des fonctions d'accès au fichiers et de communication via les "sockets" :
Fichiers Sockets
Ouvrir un flux de Fonctions open ou fopen Fonctions socket + bind
données • La cible est un nom de • La cible est définie par
fichier une adresse IP et
un numéro port TCP ou UDP
Comme on utilisera ici les adresses IP des serveurs, il sera utile d'interroger le DNS depuis un programme en C,
grâce à la fonction gethostbyname.
Or il est nécessaire que le numéro de port transmis sur le réseau soit trancrit de la même manière par le serveur et
le client : on utilisera donc les fonctions de conversion htons et ntohs pour réaliser ceci et avoir un code C
identique quelle que soit la machine utilisée.
On pourra vérifier ceci en recompilant le même code sur le dpx20 ou sur une machine Linux, qui utilisent des
codages différents ("big endian" pour les processeurs Intel)
1.2Objectifs du TP
Mettre en œuvre une communication de données entre deux machines Unix via le réseau local
et les protocoles TCP/IP, en utilisant le mécanisme des sockets.
Une des machines agira en tant que serveur pour un numéro de port donné, et l'autre machine
agira en tant que client de cette machine pour le même numéro de port.
Le modèle client-serveur
L'interaction entre applications utilisant les sockets est basée sur le modèle client-serveur:
• Un serveur est un programme offrant un ou plusieurs services en réponse à des requêtes réseau ou
même locales. C'est un processus d'arrière plan (daemon) en écoute des requêtes; lorsqu'une
requête est acceptée et le service correspondant identifié, le serveur crée en général un processus
fils (fork) qui prend en charge la communication avec ce client particulier , alors que le serveur lui-
même retourne à l'écoute d'autres requêtes.
• Un client est un processus qui envoie des requêtes à un serveur local ou réseau et attend la réponse;
en cas d'acceptation, il démarre le transfert de données; d'où le schéma:
La commande netstat (ou netstat –a) permet de connaître les connexions en cours ou en attente
RS232 (Modem)
Envoi des données par l'application : send() Réception des données par l'application :
receive()
Données
Niveau socket (TCP) Niveau socket (TCP)
Génération de l'entête TCP 4 Analyse de l'entête TCP
et ajout de l'entête TCP aux données et transmisssion des données à l'application
Segment TCP = entête TCP + données
tcp_output() tcp_input()
Génération de l'entête IP 3 Analyse de l'entête IP
et ajout de l'entête IP au segment TCP et trasmisssion du segment TCP au niveau socket
Paquet IP = entete IP + entête TCP + données
ip_output() ip_input()
Génération de l'entête Ethernet 2 Analyse de l'entête Ethernet
et ajout de l'entête Ethernet au paquet IP et transmission de l'entête Ethernet au niveau IP
Trame Ethernet = entête Ethernet + entete IP + entête TCP + données + CRC Ethernet
Emission de la séquence binaire sur le Réception de la séquence binaire sur le support
support de transmission de transmission
1
3.1Domaines
#include <sys/socket.h>
s = socket(af, type, protocol)
int s, af, type protocol;
Paramètres d’entrée :
• af : domaine ou famille d'adresse(AF_INET,AF_UNIX etc..)
• type : type de socket(SOCK_STREAM..).
• Protocole : type de protocole utilisé(TCP,UDP etc..).
Valeur retournée :
• s : Lorsque l'appel socket réussit, un descripteur est retourné, il pointe sur une entrée de la table des
fichiers ouverts qui va pointer à son tour sur une structure dynamique de la socket contenant des
données caractéristiques et de contrôle (protocole, type ...) et sur l'ensemble des routines de
manipulation de la socket. Le descripteur retourné comme tous les descripteurs de fichiers, est hérité
dans les processus fils créés par fork() .
Paramètres d’entrée :
• s : descripteur de la socket créée par la primitive socket()
• name : est un chemin ou une structure de type sockaddr permettant de préciser la famille d'adresse,
le numéro de port et l'adresse internet.
• namelen : taille en octets de sockaddr.
Paramètres d’entrée :
• s : descripteur de la socket créée par socket()
• name : pointe sur une adresse destination de type sockaddr
• namelen : taille de la structure de type sockaddr
⇒ En mode connecté (protocole TCP par exemple). l'établissement d'une connexion est nécessaire avant tout
échange de données.
⇒ En mode datagramme, connect() indique au 'noyau' la destination des datagrammes à transmettre
ultérieurement.
Paramètres d’entrées :
• s : descripteur de socket
• backlog : taille de la queue des requêtes entrantes simultanées, la valeur courante du backlog = 4
ou 5;
Valeur renvoyée :
• ns : descripteur de la nouvelle socket créée
3.2.6Sélection: select()
C'est un service multiple ou multiplexage des descripteurs. Un serveur peut attendre des connexions sur plusieurs
sockets pour gérer plusieurs services; mais il peut également gérer d'autres descripteurs que ceux des sockets
(fonction d'émulation de type remote login gérant une connexion socket et le terminal client...)
#include <sys/time.h>
n_ready = select(ndes, indes, outdes, exdes, timout)
int n_ready, ndes, *indes, *outdes, *exdes;
struct timeval *timout;
Paramètres d’entrée :
• ndes : nombre de descripteurs
• indes, outdes, exdes : pointeurs sur des bits maps permettant de vérifier les descripteurs en
lecture (indes), écriture (outdes) et événements exceptionnels (exdes).
timout : adresse d'un entier indiquant le timout d'attente: une valeur 0 bloque l'appel jusqu'à ce qu'un
descripteur devienne prêt.
3.2.7Emission de données
Plusieurs primitives sont disponibles pour le transfert de données: write() , send() , sendto() , sendmsg()
write()
Paramètres d’entrée :
• des : descripteur fichier ou socket.
send()
Paramètres d’entrée :
• s : descripteur de la socket déjà créée.
• msg : pointe sur le message (séquence d'octets) à transmettre
• flags : contrôle de transmission, les données express par exemple, ou la non utilisation de la table
de routage locale...
sento()
Paramètres d’entrée :
• to : pointe sur une adresse destination; sendto s'applique aux datagrammes.
3.2.8Réception de données
Les appels système sont similaires à ceux de l'émission de données:
cette primitive permet une fermeture partielle ou totale d'une connexion full-duplex
⇒ how = 0 fermeture en réception
⇒ how = 1 fermeture en émission
⇒ how = 2 fetmeture des deux sens de transmission
Cette primitive permet de créer une paire de sockets connectées, identifiées par les descripteurs sv [0],
sv[1]; d, type, protocol désignent le domaine, le type et le protocole; c'est une généralisation du pipe simple
d'UNIX mais avec cette différence que chacune des sockets sv[0], sv[1] peut être utilisée en lecture ou en
écriture; la communication entre processus utilisant la paire de sockets se déroule en full duplex.
Diverses autres primitives sont disponibles dont celles bien pratiques permettant d'avoir des informations
sur les hosts, les services, les réseaux et les protocoles:
• gethostbyname(name),
• getservbyname(name, proto),
• getnetbyname(name),
• getprotobyname (name), etc.
Ces différentes primitives retournent un pointeur sur une structure appropriée dont le type est défini
dans /usr/include/netdb.h (hostent, servent, netent, protoent...).
On a dans le même ordre d'idée les primitives:
• gethostname (name, namelen) : nom de la machine locale
• sethostname (name, namelin) : assigner un nom à la machine
• getpeername (s, name, namelen) : nom de la machine partenaire, etc.