Réseaux · C1 Principes · Chapitre 2 · 4 h
Modèles en couches
Pourquoi découper en couches ; le modèle OSI et le modèle TCP/IP ; encapsulation et décapsulation ; la distinction entre protocole et service.
Voici l'idée maîtresse de tout le cours, celle sans laquelle les réseaux seraient un chaos ingérable. Un réseau doit résoudre des dizaines de problèmes très différents : transmettre des bits sur un fil, trouver la bonne machine parmi des milliards, rattraper des paquets perdus, afficher une page web. Vouloir tout traiter d'un bloc serait impossible. La solution, trouvée très tôt, est de découper en couches.
Une fois ce modèle en tête, chaque protocole du reste du cours — Ethernet, IP, TCP, HTTP, DNS — prendra une place précise, et les huit chapitres suivants ne feront que remplir les cases. C'est le plan du cours autant qu'une technique.
Pourquoi découper en couches
Le principe est celui de la séparation des préoccupations : on empile des couches, chacune chargée d'un problème, chacune offrant un service à la couche au-dessus et s'appuyant sur le service de la couche en dessous. Une couche ne sait rien de ce que font les autres au détail — elle connaît seulement l'interface : ce qu'elle reçoit d'en haut, ce qu'elle demande en bas.
Trois bénéfices en découlent, et ils sont considérables :
- Indépendance. On peut remplacer une couche sans toucher aux autres. Passer du câble au Wi-Fi change la couche basse ; TCP et HTTP au-dessus ne s'en aperçoivent pas. Passer de HTTP à HTTPS change le haut ; IP en dessous ne change pas.
- Interopérabilité. Tant que deux implémentations respectent l'interface d'une couche, elles coopèrent — quels que soient leur fabricant, leur système, leur langage. C'est ce qui permet à un téléphone Android de parler à un serveur Linux via un routeur d'une troisième marque.
- Maîtrise de la complexité. On raisonne sur une couche à la fois. C'est aussi ce qui rend le dépannage méthodique — le chapitre 9 diagnostiquera une panne couche par couche.
Le modèle OSI : sept couches de référence
Le modèle OSI (Open Systems Interconnection) est le modèle théorique de référence, en sept couches. On ne l'implémente pas tel quel, mais son vocabulaire est universel : dire « c'est un problème de couche 3 » suppose ce modèle.
| N° | Couche | Rôle | Exemple |
|---|---|---|---|
| 7 | Application | services à l'utilisateur | HTTP, DNS |
| 6 | Présentation | format, chiffrement, encodage | TLS, formats |
| 5 | Session | ouverture/suivi de dialogues | — |
| 4 | Transport | fiabilité de bout en bout, ports | TCP, UDP |
| 3 | Réseau | adressage et routage global | IP |
| 2 | Liaison | trames sur un lien local, adresse MAC | Ethernet, Wi-Fi |
| 1 | Physique | bits sur le support | câble, fibre, ondes |
Retenez surtout la numérotation : « couche 2 », « couche 3 », « couche 7 » sont des expressions du métier. Un commutateur est un équipement « de couche 2 », un routeur « de couche 3 » — le chapitre 4 et le chapitre 6 le montreront.
Le modèle TCP/IP : quatre couches réelles
Le modèle TCP/IP est celui qu'Internet emploie réellement. Plus simple, en quatre couches, il regroupe certaines couches OSI :
| Couche TCP/IP | Correspond à OSI | Protocoles | Vu au chapitre |
|---|---|---|---|
| Application | 5, 6, 7 | HTTP, DNS, DHCP | 8 |
| Transport | 4 | TCP, UDP | 7 |
| Réseau (Internet) | 3 | IP, ICMP | 5 et 6 |
| Accès réseau | 1, 2 | Ethernet, Wi-Fi | 3 et 4 |
Ce tableau est le plan du cours. On montera les couches de bas en haut : la couche accès réseau (chapitres 3-4), la couche réseau et son cœur, l'adressage IP (chapitres 5-6), la couche transport (chapitre 7), la couche application (chapitre 8).
Deux modèles, deux usages : OSI pour parler et raisonner (les sept couches, le vocabulaire), TCP/IP pour comprendre Internet (les quatre couches, les vrais protocoles). Ils ne s'opposent pas ; on emploie les deux.
Quiz · 1 question
Une entreprise remplace tous ses câbles Ethernet par du Wi-Fi. Quelles couches doivent changer, et pourquoi les applications continuent-elles de fonctionner sans modification ?
- Toutes les couches, car changer le support impose de tout réécrire — tout réécrire
- Seules les couches basses (physique et liaison) changent ; grâce à l'indépendance des couches, IP, TCP et les applications au-dessus ne s'en aperçoivent pas — indépendance des couches basses
- Seule la couche application change, car c'est elle qui gère la connexion sans fil — application
Réponse : Le passage du câble au Wi-Fi ne concerne que les couches PHYSIQUE (le support : ondes au lieu de cuivre) et LIAISON (Wi-Fi au lieu d'Ethernet). C'est précisément le bénéfice du modèle en couches : chaque couche n'offre qu'un service à celle du dessus. IP demande « achemine ce paquet sur le lien », sans savoir si le lien est un fil ou une onde. TCP et les applications, encore au-dessus, ignorent totalement le changement. L'indépendance des couches rend l'évolution possible sans tout réécrire.
Encapsulation et décapsulation
Comment les couches coopèrent-elles concrètement ? Par encapsulation. Quand une donnée descend
la pile à l'émission, chaque couche l'enveloppe dans son propre en-tête — comme des poupées
russes. Sur GET /index.html :
application : [HTTP] GET /index.htmltransport : [TCP port=80] [HTTP] GET /index.htmlréseau : [IP dst=...] [TCP port=80] [HTTP] GET /index.htmlliaison : [ETH][IP dst=...] [TCP port=80] [HTTP] GET /index.html ← sur le câbleÀ la réception, l'opération inverse — la décapsulation : chaque couche lit son en-tête, le retire, et transmet le reste à la couche au-dessus. La machine réceptrice défait exactement ce que l'émettrice a construit, dans l'ordre inverse.
Le vocabulaire de l'unité de données change à chaque niveau, et il faut le connaître : on parle de trame en couche liaison, de paquet (ou datagramme) en couche réseau, de segment en couche transport, de message en application. C'est toujours la même donnée, vue à travers un en-tête différent.
Le point le plus important, celui qui fait toute la puissance du modèle : chaque couche ne lit que son propre en-tête et ignore le contenu qu'elle transporte. Un routeur (couche 3) lit l'en-tête IP pour décider où envoyer le paquet — il ne regarde jamais le HTTP à l'intérieur. C'est cette indifférence au contenu qui rend les couches indépendantes, et c'est exactement ce que Wireshark vous montrera : les en-têtes emboîtés, du câble vers l'application.
Protocole et service : ne pas confondre
Dernière distinction, discrète mais structurante. Un service est ce qu'une couche offre — son interface, le « quoi ». Un protocole est comment deux machines de même couche communiquent — les règles, le « comment ».
La couche transport offre un service à l'application : « transmets ces données de façon fiable ». Elle le réalise par un protocole, TCP, avec ses règles précises d'échange (chapitre 7). L'appli ne connaît que le service (« fiable ») ; elle ignore le protocole (poignée de main, numéros de séquence). C'est pourquoi on peut, en principe, changer de protocole sans changer le service rendu — la promesse de l'indépendance des couches, encore.
Quiz · 1 question
À la réception d'une trame, dans quel ordre les couches traitent-elles les en-têtes, et que fait chacune ?
- De l'application vers le physique : chaque couche ajoute son en-tête — ajout d'en-têtes
- Du physique vers l'application (décapsulation) : chaque couche lit puis retire SON en-tête, et transmet le reste à la couche au-dessus — décapsulation de bas en haut
- Toutes les couches lisent tous les en-têtes simultanément — lecture simultanée
Réponse : À la réception, on remonte la pile de bas en haut — c'est la décapsulation, l'inverse exact de l'encapsulation faite à l'émission. La couche liaison lit et retire son en-tête Ethernet, passe le reste à la couche réseau qui retire l'en-tête IP, et ainsi de suite jusqu'à l'application qui récupère la donnée d'origine. Chaque couche ne traite QUE son en-tête et ignore le contenu transporté. L'ajout d'en-têtes, lui, se fait à l'ÉMISSION (encapsulation), de haut en bas.
À vous
L'exercice rend l'encapsulation tangible. À l'émission, vous faites descendre une donnée dans la pile, chaque couche ajoutant son en-tête ; à la réception, vous la faites remonter, chaque couche retirant le sien dans l'ordre inverse — et vous vérifiez qu'on retrouve la donnée d'origine, intacte.
Le point à saisir en le codant : chaque couche ne touche qu'à son en-tête et ignore ce qu'elle transporte. C'est cette indifférence au contenu qui autorise à changer une couche sans toucher aux autres — et c'est exactement ce que Wireshark affichera en TP, les en-têtes emboîtés les uns dans les autres.
Exercice de code
Cassez un invariant par des attributs publics, encapsulez, puis réparez la fuite de référence.
Point de départ
// ── 1. Attributs publics : l'invariant ne tient à rien ────────────────────
class LivreOuvert {
constructor(titre) {
this.titre = titre;
this.disponible = true;
this.emprunteur = null;
}
// Invariant voulu : emprunteur non nul <=> disponible faux.
emprunter(qui) {
if (!this.disponible) return false;
this.disponible = false;
this.emprunteur = qui;
return true;
}
invariantOk() {
return (this.emprunteur === null) === this.disponible;
}
toString() {
return this.titre + " [" + (this.disponible ? "libre" : "pris par " + this.emprunteur) + "]";
}
}
// ── 2. Version encapsulée ─────────────────────────────────────────────────
class Livre {
#titre; #disponible; #emprunteurs; // # = champ réellement privé
constructor(titre) {
if (!titre) throw new Error("un livre doit avoir un titre");
this.#titre = titre;
this.#disponible = true;
this.#emprunteurs = [];
}
get titre() { return this.#titre; }
estDisponible() { return this.#disponible; }
emprunter(qui) {
// ← à écrire : refuser si déjà emprunté, sinon enregistrer l'emprunteur
return false;
}
rendre() { this.#disponible = true; }
// ← FUITE : ce getter rend la liste INTERNE, que l'appelant peut vider.
getEmprunteurs() { return this.#emprunteurs; }
}
// ── À VOUS ────────────────────────────────────────────────────────────────
// 1. Cassez l'invariant de LivreOuvert en DEUX lignes, sans appeler emprunter.
// 2. Écrivez emprunter() dans Livre, et vérifiez que la même attaque échoue.
// 3. Réparez la fuite de getEmprunteurs, de deux façons : copie défensive,
// puis exposition d'une valeur immuable.
// 4. Écrivez la même opération « emprunter si disponible » chez l'appelant,
// puis dans l'objet. Que se passe-t-il quand la règle change ?
const a = new LivreOuvert("Dune");
console.log(" " + a.toString() + " invariant :", a.invariantOk());
Solution
class LivreOuvert {
constructor(titre) { this.titre = titre; this.disponible = true; this.emprunteur = null; }
emprunter(qui) {
if (!this.disponible) return false;
this.disponible = false; this.emprunteur = qui; return true;
}
invariantOk() { return (this.emprunteur === null) === this.disponible; }
toString() {
return this.titre + " [" + (this.disponible ? "libre" : "pris par " + this.emprunteur) + "]";
}
}
console.log("— 1. attributs publics : deux lignes suffisent —");
const a = new LivreOuvert("Dune");
console.log(" départ : " + a.toString() + " invariant : " + a.invariantOk());
a.emprunteur = "Ana"; // on contourne entièrement emprunter()
a.disponible = true; // et l'on ment sur la disponibilité
console.log(" après : " + a.toString() + " invariant : " + a.invariantOk());
console.log(" Le livre est « libre » et pris par Ana. Aucune erreur, aucune trace.");
class Livre {
#titre; #disponible; #emprunteurs;
constructor(titre) {
if (!titre) throw new Error("un livre doit avoir un titre");
this.#titre = titre;
this.#disponible = true;
this.#emprunteurs = [];
}
get titre() { return this.#titre; }
estDisponible() { return this.#disponible; }
emprunter(qui) {
// La règle, en un seul endroit — et cette fois on ne peut plus l'éviter.
if (!this.#disponible) return false;
if (!qui) throw new Error("emprunteur non renseigné");
this.#disponible = false;
this.#emprunteurs.push(qui);
return true;
}
rendre() { this.#disponible = true; }
// Copie défensive : l'appelant reçoit SA liste, pas la nôtre.
getEmprunteurs() { return [...this.#emprunteurs]; }
// Mieux encore : n'exposer qu'une valeur immuable, ici un simple compte.
get nombreEmprunts() { return this.#emprunteurs.length; }
toString() {
return this.#titre + " [" + (this.#disponible ? "libre" : "emprunté") +
", " + this.#emprunteurs.length + " emprunt(s)]";
}
}
console.log("");
console.log("— 2. la même attaque, sur la version encapsulée —");
const b = new Livre("Dune");
b.emprunter("Ana");
b.disponible = true; // crée un champ PUBLIC sans rapport, inoffensif
console.log(" " + b.toString());
console.log(" estDisponible() rend toujours " + b.estDisponible() +
" : le champ privé est intact, l'invariant tient.");
try { console.log(b.#titre); } catch (e) { console.log(" accès direct à #titre : refusé"); }
console.log("");
console.log("— 3. la fuite de référence —");
const c = new Livre("Solaris");
c.emprunter("Bo"); c.rendre(); c.emprunter("Cy");
const liste = c.getEmprunteurs();
liste.length = 0; // l'appelant vide SA copie
console.log(" après que l'appelant a vidé la liste reçue : " + c.toString());
console.log(" Sans la copie défensive, le compte serait tombé à 0 : l'appelant");
console.log(" aurait modifié l'état interne sans passer par aucune méthode.");
console.log(" nombreEmprunts (valeur immuable) : " + c.nombreEmprunts + " — rien à fuir.");
console.log("");
console.log("— 4. dire, ne pas demander —");
// Chez l'appelant : la règle est ici, donc dupliquée partout où l'on emprunte.
function emprunterChezAppelant(livre, qui) {
if (livre.estDisponible()) { livre.emprunter(qui); return true; }
return false;
}
// Dans l'objet : la règle est là où vit la donnée.
const d = new Livre("Ubik");
console.log(" premier emprunt : " + d.emprunter("Ana"));
console.log(" second emprunt : " + d.emprunter("Bo") + " (refusé par l'objet)");
console.log(" Le jour où la règle devient « deux emprunts simultanés autorisés »,");
console.log(" la version « chez l'appelant » demande de retrouver tous les appels ;");
console.log(" la version « dans l'objet » demande de modifier une méthode.");
Ce que la suite en fait
Le modèle en couches est le squelette du cours. Les huit chapitres qui suivent le remplissent de bas en haut, et vous pourrez à chaque instant situer où vous êtes dans la pile.
On commence par le bas, au plus près du matériel. Le chapitre 3 traite la couche physique — comment des bits deviennent un signal sur un support — et le chapitre 4 la couche liaison — comment deux machines d'un même réseau local se parlent, avec Ethernet, les adresses MAC et le commutateur. Gardez le tableau TCP/IP sous les yeux : c'est votre carte.
À retenir
Flashcards · 4 cartes
- Pourquoi découpe-t-on un réseau en couches, et quels bénéfices cela apporte-t-il ?
- Par séparation des préoccupations : chaque couche traite UN problème, offre un service à celle du dessus et s'appuie sur celle du dessous, sans connaître leur fonctionnement interne. Bénéfices : indépendance (changer une couche sans toucher aux autres — câble → Wi-Fi, HTTP → HTTPS), interopérabilité (des implémentations de fabricants différents coopèrent), et maîtrise de la complexité (on raisonne et on dépanne une couche à la fois).
- Quelles sont les 4 couches du modèle TCP/IP, et à quoi sert chacune ?
- Application (HTTP, DNS, DHCP : services à l'utilisateur), Transport (TCP, UDP : fiabilité de bout en bout, ports), Réseau/Internet (IP, ICMP : adressage et routage global), Accès réseau (Ethernet, Wi-Fi : trames sur le lien local). C'est le modèle qu'Internet emploie réellement ; OSI (7 couches) est le modèle théorique de référence pour le vocabulaire (« couche 2 », « couche 3 »).
- Qu'est-ce que l'encapsulation, et quel principe la rend puissante ?
- À l'émission, chaque couche enveloppe la donnée dans SON en-tête (comme des poupées russes) en descendant la pile ; à la réception, chaque couche lit puis retire son en-tête en remontant (décapsulation). Le principe clé : chaque couche ne lit QUE son en-tête et ignore le contenu transporté — un routeur lit IP sans regarder HTTP. C'est cette indifférence au contenu qui rend les couches indépendantes. L'unité s'appelle trame (2), paquet (3), segment (4), message (7).
- Quelle est la différence entre un service et un protocole ?
- Un service est CE QU'une couche offre (son interface, le « quoi » : « transmettre de façon fiable »). Un protocole est COMMENT deux machines de même couche communiquent (les règles, le « comment » : la poignée de main et les numéros de séquence de TCP). L'application connaît le service (« fiable »), pas le protocole — d'où la possibilité, en principe, de changer de protocole sans changer le service rendu.