Debian logo [inetdoc.LINUX]

2. Contexte de développement

L'objectif de développement étant l'initiation, on se limite à un code minimaliste utilisant deux programmes distincts : un serveur et un client. Ces deux programmes échangent des chaînes caractères. Le «client» émet un message que le «serveur» traite et retransmet vers le «client». Le traitement est tout aussi minimaliste. Il s'agit de convertir la chaîne de caractères en majuscules.

2.1. Système d'exploitation

Le schéma ci-dessous positionne les couches de la modélisation des communications réseau vis-à-vis du système d'exploitation.

Les pilotes de périphériques et les protocoles implantés depuis la couche physique jusqu'à la couche transport font partie du sous-système réseau du noyau du système d'exploitation.

Le programme utilisateur est lancé à partir de la couche Shell et est exécuté au niveau application.

L'utilisation de socket revient à ouvrir un canal de communication entre la couche application et la couche transport. La programmation des sockets se fait à l'aide de bibliothèques standard présentées ci-après : Section 2.4, « Bibliothèques utilisées ».

2.2. Instructions de compilation

Il est possible de compiler ces deux programmes en l'état sur n'importe quel système GNU/Linux. Il suffit d'appeler le compilateur C++ de la chaîne de développement GNU en désignant le nom du programme exécutable avec l'option -o.

$ g++ -o udp-client udp-client.cc
$ g++ -o udp-server udp-server.cc
$ ls -l udp*
-rwxr-xr-x 1 phil phil 12217  3 mars  16:29 udp-client
-rw-r--r-- 1 phil phil  3853  3 mars  16:29 udp-client.cc
-rwxr-xr-x 1 phil phil 11084  3 mars  16:30 udp-server
-rw-r--r-- 1 phil phil  2744  3 mars  16:29 udp-server.cc

2.3. Instructions d'exécution

L'exécution du programme est aussi assez triviale. On peut exécuter le client et le serveur sur le même hôte dans deux Shells distincts et utiliser l'interface de boucle locale pour les communications réseau.

Le programme serveur, udp-server.cc
$ ./udp-server
Entrez le numéro de port utilisé en écoute (entre 1500 et 65000) : 4000
Attente de requête sur le port 4000
  Depuis 127.0.0.1:60471
  Message reçu : texte du message
Le programme client, udp-client.cc
$ ./udp-client
Entrez le nom du serveur ou sont adresse IP : 127.0.0.1
Entrez le numéro de port du serveur : 4000

Entrez quelques caractères au clavier.
Le serveur les modfiera et les renverra.
Pour sortir, entrez une ligne avec le caractère '.' uniquement
Si une ligne dépasse 100 caractères,
seuls les 100 premiers caractères seront utilisés.

Saisie du message : texte du message
Message traité : TEXTE DU MESSAGE
Saisie du message : .

2.4. Bibliothèques utilisées

Les deux programmes utilisent les mêmes fonctions disponibles à partir des bibliothèques standards.

libc6-dev, netdb.h

Opérations sur les bases de données réseau. Ici, c'est la fonction gethostbyname() qui est utilisée. Elle renvoie une structure de type hostent pour l'hôte name. La chaîne name est soit un nom d'hôte, soit une adresse IPv4 en notation pointée standard, soit une adresse IPv6 avec la notation points-virgules et points. Pour obtenir plus d'informations, il faut consulter les pages de manuels : man gethostbyname.

libc6-dev, netinet/in.h

Famille du protocole Internet. Ici, plusieurs fonctions sont utilisées à partir du paramètre de description de socket sockaddr_in. Les quatre fonctions importantes traitent de la conversion des nombres représentés suivant l'hôte (octet le moins significatif en premier sur processeur Intel x86) ou les définitions des en-têtes réseau (octet le plus significatif en premier).

  • htonl() et htons() : conversion d'un entier long et d'un entier court depuis la représentation hôte (octet le moins significatif en premier ou Least Significant Byte First) vers la représentation réseau standard (octet le plus significatif en premier ou Most Significant Byte First).

  • ntohl() et ntohs() : fonctions opposées aux précédentes. Conversion de la représentation réseau vers la représentation hôte.

libstdc++6-dev, iostream

Opérations sur les flux d'entrées/sorties de base tels que l'écran et le clavier. Ici, toutes les opérations de saisie de nom d'hôte, d'adresse IP, de numéro de port ou de texte sont gérées à l'aide des fonctions usuelles du langage C++. Ces fonctions sont les seules qui soient spécifiques au langage C++.

D'une manière générale, toutes les fonctions sont documentées à l'aide des pages de manuels Unix classiques. Soit on entre directement à la console une commande du type : man inet_ntoa, soit on utilise l'aide du gestionnaire graphique pour accéder aux mêmes informations en saisissant une URL du type suivant à partir du gestionnaire de fichiers : man:/inet_ntoa.

2.5. Choix du protocole de transport

Au dessus du protocole de couche réseau IP, on doit choisir entre deux protocoles de couche transport : TCP ou UDP.

Le protocole TCP est le premier protocole développé. Il «porte la moitié» de la philosophie du modèle Internet. Cette philosophie veut que la couche transport soit le lieu de la fiabilisation des communications. Ce protocole fonctionne donc en mode connecté et contient tout les outils nécessaires à l'établissement, au maintien et à la libération de connexion. De plus, des numéros de séquences garantissent l'intégrité de la transmission et le fenêtrage de ces numéros de séquences assure un contrôle de congestion. Tout ces mécanismes ne sont pas évidents à maîtriser pour un public débutant.

Le protocole UDP a été développé après TCP. La philosophie de ce mode de transport suppose que le réseau de communication est intrinsèquement fiable et qu'il n'est pas nécessaire de garantir l'intégrité des transmissions et de contrôler la congestion. On dit que le protocole UDP n'est pas orienté connexion ; ce qui a pour conséquence d'alléger considérablement les mécanismes de transport.

L'objectif du présent document étant d'initier à l'utilisation des sockets, on s'appuie sur le protocole de transport le plus simple : UDP. En termes de développement, les différences de mise en œuvre des sockets sont minimes. C'est à l'analyse réseau que la différence se fait. UDP est plus facile à utiliser avec un public débutant.

Pour plus d'informations, consulter le support Modélisations réseau.

2.6. Sockets & protocole de transport UDP

Le schéma ci-dessous présente les sous-programmes sélectionnés côté client et côté serveur pour la mise en œuvre des sockets avec le protocole de transport UDP.

Les appels de sous-programmes avec les passages de paramètres sont détaillés dans les sections suivantes.