C1 — PrincipesDans le dialogue d’impression, choisissez « Enregistrer au format PDF » comme destination.
Retour

Licence 1 · Réseaux

Cours 1Principes

Poser ce qu'est un réseau et pourquoi on le pense en couches — le modèle qui structure tout le reste du cours.

2 chapitres · 8 h de travail estimé

  1. 1. Introduction aux réseaux4 h
  2. 2. Modèles en couches4 h

Chapitre 1 · 4 h

Introduction aux réseaux

Ce qu'est un réseau ; LAN, MAN, WAN ; topologies ; commutation de circuits contre commutation de paquets ; débit, latence, bande passante.

En 1969, quatre ordinateurs américains sont reliés pour former ARPANET. Aujourd'hui, plus de cinq milliards de personnes partagent un même réseau planétaire, et vous y êtes connecté en lisant cette page. Entre les deux, aucune rupture technologique unique : la même poignée d'idées, répétée et empilée. Ce cours démonte ces idées une à une.

Ce premier chapitre pose le vocabulaire et, surtout, les grandeurs qui mesurent un réseau. Il paraît descriptif ; il contient déjà la confusion la plus tenace de la matière — celle entre débit et latence — que nous allons désamorcer par le calcul plutôt que par une phrase.

Qu'est-ce qu'un réseau ?

Un réseau informatique est un ensemble de machines reliées pour échanger de l'information. « Machine » se prend au sens large : un ordinateur, un téléphone, une imprimante, un capteur, une voiture. Chacune est un nœud ; les échanges suivent des règles communes, les protocoles, qui occuperont tout le cours.

L'intérêt d'un réseau croît vite avec sa taille : relier nn machines crée de l'ordre de n2n^2 communications possibles. C'est ce qui explique qu'un réseau, une fois amorcé, tende à absorber tous les autres — l'histoire d'Internet est celle de réseaux séparés qui ont fini par se raccorder à un seul.

Classer par la taille : LAN, MAN, WAN

On classe d'abord les réseaux par leur étendue géographique, parce que la distance change les techniques employées.

SigleNomÉtendueExemple
LANLocal Area Networkun bâtiment, un sitele réseau d'une salle de TP, d'une maison
MANMetropolitan Area Networkune villel'interconnexion des sites d'une université
WANWide Area Networkun pays, le mondeInternet, le réseau d'une multinationale

La distinction n'est pas qu'une affaire de taille : un LAN est rapide (courtes distances, faible latence, un seul propriétaire), un WAN est lent et hétérogène (grandes distances, équipements de multiples opérateurs). Internet est le WAN par excellence — non pas un réseau, mais un réseau de réseaux, ce que son nom dit littéralement.

Les topologies

La topologie décrit la forme des liaisons — qui est connecté à qui.

  • Bus : toutes les machines partagent un même câble. Simple et bon marché, mais une coupure du câble paralyse tout, et les machines se disputent le médium (d'où le CSMA/CD du chapitre 4).
  • Étoile : toutes les machines se relient à un équipement central (commutateur). C'est la topologie dominante aujourd'hui : une panne de câble n'isole qu'une machine, et le central arbitre les échanges.
  • Anneau : chaque machine est reliée à la suivante en boucle. Historique.
  • Maillée : les nœuds sont reliés par des chemins redondants. Coûteuse, mais résistante aux pannes — c'est la structure du cœur d'Internet, où plusieurs routes mènent au même endroit.

Un réseau réel combine ces formes à différentes échelles : des étoiles locales, raccordées par un cœur maillé. La redondance du maillage est ce qui permet à Internet de survivre à la coupure d'un câble sous-marin sans que l'utilisateur s'en aperçoive.

Commutation de circuits contre commutation de paquets

Voici le choix fondateur, celui qui distingue le téléphone d'antan de l'Internet. Comment transporter l'information à travers le réseau ?

La commutation de circuits, héritée du téléphone, réserve un chemin de bout en bout pour toute la durée de la communication. Le circuit est dédié : débit garanti, mais gaspillé dès qu'on se tait, et le réseau refuse de nouvelles communications quand tous les circuits sont pris.

La commutation de paquets, celle d'Internet, découpe l'information en petits morceaux autonomes, les paquets, envoyés indépendamment. Chaque paquet porte son adresse de destination ; les équipements du réseau le relaient de proche en proche, et différents paquets peuvent même emprunter des routes différentes.

CircuitsPaquets
Ressourcechemin réservépartagée à la demande
Efficacitégaspillée aux silencesremplie par plusieurs flux
Robustessele circuit tombe, tout tombeun paquet se reroute
Garantiedébit garanti« au mieux »

La commutation de paquets a gagné pour deux raisons : elle partage efficacement les liens entre de nombreux flux intermittents (le trafic informatique est fait de rafales, pas de flux continus), et elle résiste aux pannes — si un lien tombe, les paquets suivants contournent. Son prix est l'absence de garantie native : un paquet peut être perdu, dupliqué, désordonné. Rattraper cela sera le travail de TCP, au chapitre 7.

Quiz · 1 question

Pourquoi la commutation de paquets utilise-t-elle mieux les liens du réseau que la commutation de circuits, pour du trafic informatique ?

  • Parce qu'elle réserve un chemin dédié, garantissant le débit à chaque communicationchemin dédié
  • Parce que le trafic informatique est fait de rafales avec des silences ; le partage à la demande remplit les liens avec plusieurs flux au lieu de réserver un chemin qui reste inutilisé aux silencespartage des rafales
  • Parce que les paquets sont toujours transmis plus vite que les circuitsvitesse brute

Réponse : Le trafic informatique est intermittent : on charge une page, on lit, on ne transmet rien, puis on clique à nouveau. Un circuit réservé resterait inutilisé pendant tous ces silences, mais indisponible pour les autres. La commutation de paquets partage le lien à la demande : pendant qu'un flux se tait, un autre passe. Elle ne transmet pas « plus vite » un paquet donné, et elle ne garantit rien — elle utilise mieux la ressource commune, ce qui est l'objectif quand le trafic est fait de rafales.

Les grandeurs : débit, latence, bande passante

Trois nombres mesurent un réseau, et les confondre est l'erreur la plus répandue.

Le débit (ou bande passante, dans l'usage courant) est la quantité de données par seconde qu'un lien peut écouler : en bits par seconde (bit/s, Mbit/s, Gbit/s). C'est la largeur du tuyau.

La latence est le délai pour qu'un bit traverse le lien d'un bout à l'autre : en millisecondes. C'est la longueur du tuyau. On mesure souvent le temps aller-retour (le RTT, round-trip time), celui que renvoie la commande ping.

Ces deux grandeurs sont indépendantes, et c'est le point à graver. Un lien peut avoir un énorme débit et une énorme latence (une liaison satellite : beaucoup de données par seconde, mais un quart de seconde de délai à cause de la distance), ou l'inverse. Le temps total d'un transfert combine les deux :

temps=latencedeˊlai fixe+tailledeˊbittemps d’eˊmission.\text{temps} = \underbrace{\text{latence}}_{\text{délai fixe}} + \underbrace{\frac{\text{taille}}{\text{débit}}}_{\text{temps d'émission}}.

La conséquence pratique est décisive. Pour un petit transfert (une requête web), c'est la latence qui domine : élargir le tuyau ne change rien. Pour un gros transfert (une sauvegarde), c'est le débit qui domine : la latence devient négligeable. Optimiser un réseau commence donc par savoir laquelle des deux grandeurs limite — ce sont deux problèmes différents, avec deux solutions différentes. L'exercice vous le fera calculer, jusqu'au cas extrême du camion de disques durs.

Quiz · 1 question

Un joueur en ligne se plaint de « lag » alors que son forfait affiche 1 Gbit/s. Augmenter le débit à 2 Gbit/s réglera-t-il le problème ?

  • Oui : plus de débit signifie toujours une meilleure réactivitéplus de débit = mieux
  • Non : le jeu envoie de petits messages fréquents ; il est limité par la LATENCE (le délai aller-retour), pas par le débit — qu'il faut réduire, pas élargir le tuyaulimité par la latence
  • Oui, mais seulement si la latence augmente aussilatence en hausse

Réponse : Un jeu en ligne échange de petits messages très fréquents (position, actions). Leur temps d'émission est infime : ce qui compte est la LATENCE, le délai entre l'action et sa prise en compte par le serveur. Doubler le débit n'y change rien — le tuyau est déjà bien plus large que nécessaire. Le « lag » se combat en réduisant la latence (route plus courte, meilleur serveur, moins de sauts), pas en élargissant le tuyau. C'est l'illustration même de l'indépendance entre débit et latence.

À vous

L'exercice attaque la confusion débit/latence par le calcul. Vous mesurez le temps de transfert d'une petite requête puis d'un gros fichier sur le même lien — et vous constatez que la première est limitée par la latence, le second par le débit. Puis vous comparez « transférer 100 To par Internet » à « les transférer par un camion de disques durs », et vous découvrez, chiffres à l'appui, pourquoi le camion gagne.

C'est le meilleur antidote à l'idée fausse que « plus de débit = plus rapide » : cela dépend entièrement de ce qu'on transfère.

Exercice de code

Calculez le temps de transfert (latence + taille/débit) pour une petite requête puis un gros fichier sur le même lien, et comparez « 100 To par Internet » à « 100 To par camion de disques ». Vous verrez pourquoi débit et latence sont deux grandeurs indépendantes qu'on ne doit jamais confondre.

Point de départ

// Temps pour transférer un fichier = temps d'ACHEMINEMENT (la latence, une
// durée fixe pour aller-retour) + temps d'ÉMISSION (taille / débit).
//
//   débit    : combien de bits par seconde le lien peut écouler (bit/s)
//   latence  : temps qu'un bit met à traverser le lien (s)
//
// Attention aux unités : 1 octet = 8 bits ; débits en bits/s, tailles en octets.

function tempsTransfert(tailleOctets, debitBitParSec, latenceSec) {
  const tailleBits = tailleOctets * 8;
  const tempsEmission = tailleBits / debitBitParSec;
  return latenceSec + tempsEmission;
}

// ── À VOUS (1) : deux scénarios ─────────────────────────────────────────────
// Scénario A : une petite requête web de 2 ko sur une fibre à 100 Mbit/s,
//   latence 20 ms.
// Scénario B : le MÊME lien, mais un fichier de 5 Go (une sauvegarde).
const ko = 1000, Mo = 1e6, Go = 1e9;
const Mbit = 1e6;

const tA = tempsTransfert(2 * ko, 100 * Mbit, 0.020);   // à observer
const tB = tempsTransfert(5 * Go, 100 * Mbit, 0.020);   // à observer
console.log("A (2 ko)  :", tA.toFixed(3), "s");
console.log("B (5 Go)  :", tB.toFixed(1), "s");

// ── À VOUS (2) : le camion de disques durs ──────────────────────────────────
// Transférer 100 To d'un data-center à un autre. Deux options :
//   - Internet : lien dédié à 1 Gbit/s, latence 30 ms.
//   - Un camion qui emporte les disques : 4 h de route, mais 100 To « d'un coup ».
// Calculez les deux temps. Lequel gagne ? Que dit ce résultat sur débit vs latence ?
const To = 1e12, Gbit = 1e9, heure = 3600;
const parInternet = 0; // à compléter avec tempsTransfert(...)
const parCamion   = 0; // à compléter (indice : la "latence" du camion, c'est la route)
console.log("");
console.log("100 To par Internet :", (parInternet / heure).toFixed(1), "h");
console.log("100 To par camion   :", (parCamion   / heure).toFixed(1), "h");

Solution

const parInternet = tempsTransfert(100 * To, 1 * Gbit, 0.030);
// 100 To = 8e14 bits ; / 1e9 bit/s = 8e5 s ≈ 222 h ≈ 9,3 JOURS.
const parCamion = 4 * heure;
// Le camion : 4 h de route, peu importe la latence — il « émet » 100 To en un
// seul voyage. Débit effectif : 100 To / 4 h ≈ 55 Gbit/s. Le camion gagne
// très largement (4 h contre 9 jours).

// ── Ce que l'exercice enseigne ──────────────────────────────────────────────
//
// 1. DÉBIT et LATENCE sont deux choses INDÉPENDANTES.
//    - La latence est un DÉLAI (le temps du premier bit pour arriver). Elle
//      domine pour les petits transferts : le scénario A (2 ko) est limité par
//      les 20 ms de latence, pas par le débit — émettre 2 ko à 100 Mbit/s ne
//      prend que 0,16 ms.
//    - Le débit est un VOLUME PAR SECONDE. Il domine pour les gros transferts :
//      le scénario B (5 Go) est entièrement décidé par le débit, la latence y
//      est négligeable.
//
// 2. Le camion de disques est l'exemple canonique : ÉNORME débit (55 Gbit/s),
//    ÉNORME latence (4 h avant le premier octet). On ne l'utiliserait jamais
//    pour charger une page web (latence catastrophique), mais il bat Internet
//    pour déplacer 100 To. « Ne jamais sous-estimer la bande passante d'un
//    camion de bandes sur l'autoroute » — la boutade est un vrai principe.
//
// 3. Conséquence pratique : optimiser un réseau, c'est d'abord savoir si on
//    est limité par la latence (jeux en ligne, requêtes courtes : réduire les
//    aller-retours) ou par le débit (sauvegardes, vidéo : élargir le tuyau).
//    Ce sont deux problèmes différents, avec deux solutions différentes.

Ce que la suite en fait

Vous savez ce qu'est un réseau, comment le classer, comment l'information y circule (en paquets), et comment le mesurer. Reste une question : comment fait-on tenir ensemble tant de protocoles, de techniques et d'équipements différents sans que l'ensemble devienne ingérable ?

La réponse est l'idée la plus importante de tout le cours, celle qui structure Internet et les huit chapitres suivants : le découpage en couches. C'est l'objet du chapitre 2 — et une fois ce modèle en tête, chaque protocole que vous rencontrerez trouvera sa place dans une case précise.

À retenir

Flashcards · 4 cartes

Quelle est la différence entre commutation de circuits et commutation de paquets, et pourquoi la seconde a-t-elle gagné ?
La commutation de circuits réserve un chemin dédié pour toute la communication (débit garanti mais gaspillé aux silences). La commutation de paquets découpe l'information en paquets autonomes, relayés indépendamment de proche en proche. Elle a gagné parce qu'elle PARTAGE efficacement les liens entre des flux intermittents (le trafic est fait de rafales) et RÉSISTE aux pannes (un paquet se reroute). Son prix : aucune garantie native — c'est TCP qui la rétablira.
Quelle est la différence entre débit et latence, et laquelle domine selon le transfert ?
Le débit est la quantité de données par seconde (largeur du tuyau, en bit/s) ; la latence est le délai pour traverser le lien (longueur du tuyau, en ms). Elles sont INDÉPENDANTES. Temps de transfert = latence + taille/débit : la latence domine pour les petits transferts (requête web, jeu en ligne), le débit pour les gros (sauvegarde, vidéo). Optimiser commence par savoir laquelle des deux limite.
Que signifient LAN, MAN, WAN, et qu'est-ce qui distingue un LAN d'un WAN au-delà de la taille ?
LAN : réseau local (bâtiment, site). MAN : réseau métropolitain (ville). WAN : réseau étendu (pays, monde — Internet). Au-delà de l'étendue : un LAN est rapide, à faible latence, avec un seul propriétaire ; un WAN est plus lent, hétérogène, réparti entre de multiples opérateurs. Internet est un WAN — plus précisément un réseau de réseaux.
Quelle topologie domine aujourd'hui les réseaux locaux, et pourquoi le cœur d'Internet est-il maillé ?
L'ÉTOILE domine en local : chaque machine se relie à un commutateur central, si bien qu'une coupure de câble n'isole qu'une machine et que le central arbitre les échanges. Le cœur d'Internet est MAILLÉ (chemins redondants) pour la résistance aux pannes : plusieurs routes mènent au même endroit, donc la coupure d'un lien est contournée sans interruption visible.

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.

CoucheRôleExemple
7Applicationservices à l'utilisateurHTTP, DNS
6Présentationformat, chiffrement, encodageTLS, formats
5Sessionouverture/suivi de dialogues
4Transportfiabilité de bout en bout, portsTCP, UDP
3Réseauadressage et routage globalIP
2Liaisontrames sur un lien local, adresse MACEthernet, Wi-Fi
1Physiquebits sur le supportcâ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/IPCorrespond à OSIProtocolesVu au chapitre
Application5, 6, 7HTTP, DNS, DHCP8
Transport4TCP, UDP7
Réseau (Internet)3IP, ICMP5 et 6
Accès réseau1, 2Ethernet, Wi-Fi3 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éécriretout 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 pasindépendance des couches basses
  • Seule la couche application change, car c'est elle qui gère la connexion sans filapplication

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êteajout 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-dessusdécapsulation de bas en haut
  • Toutes les couches lisent tous les en-têtes simultanémentlecture 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.