Jour 30 Day 30 · mardi 15 septembre 2026 Tuesday 15 September 2026 DevOps Intermédiaire

TCP, UDP & le réseau du développeur TCP, UDP & the developer's network

Three-way handshake, ports, NAT, latence : le socle réseau qu'un recruteur attend d'un dev backend — et les outils pour diagnostiquer « pourquoi c'est lent » en entretien comme en prod. Three-way handshake, ports, NAT, latency: the networking foundation a recruiter expects from a backend dev — and the tools to diagnose "why is it slow" in interviews and in production.

L’essentiel

Tout ce qu’un développeur envoie sur le réseau traverse une pile de couches. Le modèle OSI à 7 couches est académique ; en pratique, quatre suffisent :

CoucheRôleExemples
ApplicatifLe sens des donnéesHTTP, DNS, gRPC, WebSocket
TransportDe processus à processus (ports)TCP, UDP, QUIC
Réseau (IP)De machine à machine, routageIPv4, IPv6, ICMP
LienLe support physique localEthernet, Wi-Fi

Chaque couche encapsule celle du dessus : votre requête HTTP part dans un segment TCP, dans un paquet IP, dans une trame Ethernet. IP ne garantit rien : les paquets peuvent se perdre, arriver en désordre ou en double. Toute la question du transport est : que fait-on de cette réalité ?

  • TCP répond : je masque tout ça. Connexion établie, octets livrés dans l’ordre, sans perte, sans doublon — au prix de latence et de mécanique.
  • UDP répond : rien. J’ajoute juste les ports à IP. Un datagramme part, il arrive ou pas — à l’application de gérer. C’est un choix, pas une négligence.

Comment ça marche

TCP est orienté connexion : avant le moindre octet utile, client et serveur se synchronisent par le three-way handshake :

Client                          Serveur
  │──────── SYN (seq=x) ─────────▶│  « je veux parler,
  │                               │    je numérote depuis x »
  │◀──── SYN-ACK (seq=y, ack=x+1)─│  « ok, moi depuis y »
  │──────── ACK (ack=y+1) ───────▶│  « reçu, on y va »
  │                               │
  │═══════ données HTTP… ════════▶│  = 1 RTT avant le
  │                               │    premier octet utile

Ce handshake coûte un aller-retour (RTT) avant toute donnée — et TLS en ajoute par-dessus. C’est pour ça que la latence, pas la bande passante, domine le temps de réponse des petites requêtes.

Une fois connecté, TCP fournit :

  • Ordre et fiabilité : chaque octet est numéroté (sequence numbers), le récepteur acquitte (ACK) ; un segment non acquitté est retransmis après timeout ou ACKs dupliqués.
  • Flow control : le récepteur annonce la taille de sa fenêtre de réception — l’émetteur n’envoie jamais plus que ce que l’autre peut absorber.
  • Congestion control : l’émetteur sonde le réseau (slow start, puis évitement de congestion) et réduit son débit dès qu’il détecte des pertes. C’est ce qui empêche Internet de s’effondrer — et ce qui fait qu’un transfert TCP démarre « doucement ».

UDP, lui, envoie des datagrammes indépendants : pas de connexion, pas d’ordre, pas de retransmission, en-tête de 8 octets. Parfait quand la retransmission n’a pas de sens : DNS (une question, une réponse — on réessaie soi-même), jeux temps réel et visio (une position vieille de 200 ms est bonne à jeter, pas à retransmettre), et QUIC, qui rebâtit fiabilité + chiffrement au-dessus d’UDP.

🎤 En entretien — « pourquoi HTTP/3 passe à UDP ? » Parce que TCP a deux problèmes que personne ne peut corriger : le handshake coûte des RTT (TCP puis TLS), et une seule perte bloque tout le flux, même les requêtes multiplexées qui n’ont rien à voir (head-of-line blocking). QUIC, construit sur UDP, fusionne transport + TLS 1.3 en un seul handshake, gère des streams indépendants (une perte ne bloque qu’un stream) et survit au changement de réseau (Wi-Fi → 4G). On ne pouvait pas modifier TCP lui-même : il est figé dans les noyaux et les middleboxes — UDP était la seule porte de sortie.

Concepts clés à maîtriser

  • Ports et sockets : l’adresse IP identifie la machine, le port (0-65535) identifie le processus. Une connexion TCP est identifiée par le quadruplet (IP src, port src, IP dst, port dst) — c’est pour ça qu’un serveur sur le port 443 sert des milliers de clients simultanés. Côté code : listen() crée la socket d’écoute, chaque accept() retourne une socket dédiée à un client.
  • NAT : votre machine en 192.168.x.x n’est pas routable sur Internet. Le routeur réécrit IP source et port sortants vers son IP publique et mémorise le mapping pour router les réponses. Conséquences : plusieurs machines partagent une IP publique, et un serveur derrière un NAT n’est pas joignable de l’extérieur sans redirection de port — d’où les techniques de traversée (STUN/TURN) de WebRTC.
  • Latence vs bande passante : la bande passante est la largeur du tuyau (Mo/s), la latence le temps d’un aller-retour (ms). Charger 100 petites ressources est limité par la latence (des dizaines de RTT), pas par le débit. Réflexes : réduire les allers-retours (HTTP/2-3, batching), rapprocher les données (CDN, cache), réutiliser les connexions (keep-alive, pools).
  • Les outils du quotidien : ss -tlnp (qui écoute sur quels ports — le réflexe sécurité), ping (latence ICMP), traceroute (le chemin, saut par saut), dig (DNS), tcpdump pour voir les paquets, et curl -w pour décomposer une requête HTTP :
# Décomposer le temps d'une requête, étape par étape
curl -w '
DNS:        %{time_namelookup}s   # résolution du nom
TCP:        %{time_connect}s      # fin du three-way handshake
TLS:        %{time_appconnect}s   # fin du handshake TLS
TTFB:       %{time_starttransfer}s # premier octet de la réponse
Total:      %{time_total}s
' -o /dev/null -s https://api.example.com/health

# Lecture : TCP - DNS ≈ 1 RTT ; TLS - TCP ≈ le coût du chiffrement ;
# TTFB - TLS ≈ le temps de calcul CÔTÉ SERVEUR.
# Si Total explose mais TTFB est bon → problème de débit/taille,
# si TTFB est mauvais → serveur lent ou trop de RTT.

💡 Le réflexe diagnostic — « l’API est lente » ne veut rien dire tant qu’on n’a pas séparé DNS / connexion / TLS / serveur / transfert. curl -w fait cette séparation en une commande : c’est la meilleure réponse possible à « comment tu débuggerais ça ? ».

En entretien

« Explique le three-way handshake. » — SYN (le client propose son numéro de séquence initial), SYN-ACK (le serveur acquitte et propose le sien), ACK (le client confirme). Les deux côtés ont synchronisé leurs numéros de séquence : la connexion est établie, au prix d’un RTT. Bonus : mentionner que TLS ajoute son propre handshake par-dessus, et que QUIC fusionne les deux.

« TCP vs UDP, lequel choisir ? » — TCP dès qu’il faut de l’exactitude : HTTP/1-2, bases de données, mail, transferts. UDP quand la fraîcheur prime sur la complétude (jeux, voix, visio), quand l’échange est minuscule (DNS), ou quand on rebâtit son propre transport au-dessus (QUIC). La question cachée : « sais-tu que la fiabilité a un coût ? »

TCPUDP
ConnexionOui (handshake, 1 RTT)Non
Ordre / fiabilitéGarantis (seq + ACK + retransmission)Aucun
Congestion controlOuiNon (à l’application)
En-tête20+ octets8 octets
UsagesHTTP/1-2, DB, SSH, mailDNS, jeux, VoIP, QUIC/HTTP-3

« Que se passe-t-il quand un paquet se perd ? » — En TCP : le récepteur acquitte le dernier octet contigu reçu ; l’émetteur retransmet sur timeout ou triple ACK dupliqué, et le congestion control réduit le débit. En UDP : rien — le datagramme est perdu, point ; c’est à l’application de décider si ça mérite un renvoi.

« Une machine derrière un NAT peut-elle recevoir une connexion entrante ? » — Pas spontanément : le NAT ne route que les réponses aux flux sortants qu’il a mémorisés. Il faut une redirection de port configurée, ou des techniques de traversée (STUN pour découvrir son adresse publique, TURN comme relais) — exactement ce que fait WebRTC.

« Pourquoi ajouter de la bande passante n’accélère pas mon API ? » — Parce que le temps d’une petite requête est dominé par les allers-retours : DNS + handshake TCP + TLS + requête ≈ 3-4 RTT avant le premier octet. À 80 ms de RTT, c’est 300 ms incompressibles quel que soit le débit. Solutions : keep-alive, HTTP/2-3, CDN, régions proches.

Pièges & idées reçues

⚠️ « UDP n’est pas fiable, donc inutilisable » — faux : « pas fiable » signifie que la couche transport ne retransmet pas, pas que les paquets se perdent en masse. Sur un bon réseau, la quasi-totalité arrive. QUIC — donc HTTP/3, donc une part énorme du web — tourne sur UDP avec une fiabilité rebâtie au-dessus.

  • « TCP garantit la livraison » — TCP garantit ordre et intégrité de ce qui arrive, et retransmet tant que la connexion vit. Si le câble est coupé, rien n’est livré : l’application doit gérer timeouts et reconnexions.
  • Confondre latence et bande passante : « on a la fibre, pourquoi c’est lent ? » — parce que 40 requêtes séquentielles × 50 ms de RTT = 2 s, fibre ou pas.
  • ping qui échoue ≠ service down : ping teste ICMP, pas votre port TCP. Beaucoup d’hôtes filtrent ICMP. Tester le service réel : curl ou nc -zv host 443.
  • Oublier que le port < 1024 exige des privilèges sous Linux — d’où les apps qui écoutent sur 3000/8080 derrière un reverse proxy qui, lui, tient le 80/443.
  • ss -tlnp avant tout debug « connection refused » : si personne n’écoute sur le port, inutile de chercher plus loin dans le réseau.

Pour aller plus loin

The essentials

Everything a developer sends over the network goes through a stack of layers. The 7-layer OSI model is academic; in practice, four are enough:

LayerRoleExamples
ApplicationThe meaning of the dataHTTP, DNS, gRPC, WebSocket
TransportProcess to process (ports)TCP, UDP, QUIC
Network (IP)Machine to machine, routingIPv4, IPv6, ICMP
LinkThe local physical mediumEthernet, Wi-Fi

Each layer encapsulates the one above: your HTTP request rides in a TCP segment, in an IP packet, in an Ethernet frame. IP guarantees nothing: packets can be lost, arrive out of order or duplicated. The whole transport question is: what do we do about that reality?

  • TCP answers: I hide all of it. Connection established, bytes delivered in order, without loss, without duplicates — at the price of latency and machinery.
  • UDP answers: nothing. I just add ports on top of IP. A datagram leaves, it arrives or it doesn’t — the application deals with it. That’s a choice, not negligence.

How it works

TCP is connection-oriented: before a single useful byte, client and server synchronize through the three-way handshake:

Client                          Server
  │──────── SYN (seq=x) ─────────▶│  "I want to talk,
  │                               │   numbering from x"
  │◀──── SYN-ACK (seq=y, ack=x+1)─│  "ok, me from y"
  │──────── ACK (ack=y+1) ───────▶│  "got it, let's go"
  │                               │
  │═══════ HTTP data… ═══════════▶│  = 1 RTT before the
  │                               │    first useful byte

This handshake costs one round trip (RTT) before any data — and TLS adds more on top. That’s why latency, not bandwidth, dominates the response time of small requests.

Once connected, TCP provides:

  • Order and reliability: every byte is numbered (sequence numbers), the receiver acknowledges (ACK); an unacknowledged segment is retransmitted after a timeout or duplicate ACKs.
  • Flow control: the receiver advertises its receive window size — the sender never sends more than the other side can absorb.
  • Congestion control: the sender probes the network (slow start, then congestion avoidance) and cuts its rate as soon as it detects losses. That’s what keeps the Internet from collapsing — and why a TCP transfer starts “slowly”.

UDP, by contrast, sends independent datagrams: no connection, no ordering, no retransmission, an 8-byte header. Perfect when retransmission makes no sense: DNS (one question, one answer — you just retry yourself), real-time games and video calls (a 200 ms-old position should be dropped, not retransmitted), and QUIC, which rebuilds reliability + encryption on top of UDP.

🎤 In an interview — “why does HTTP/3 move to UDP?” Because TCP has two problems nobody can fix: the handshake costs RTTs (TCP then TLS), and a single loss blocks the entire stream, even multiplexed requests that have nothing to do with it (head-of-line blocking). QUIC, built on UDP, merges transport + TLS 1.3 into a single handshake, manages independent streams (a loss only blocks one stream) and survives network changes (Wi-Fi → 4G). TCP itself couldn’t be changed: it’s frozen into kernels and middleboxes — UDP was the only way out.

Key concepts to master

  • Ports and sockets: the IP address identifies the machine, the port (0-65535) identifies the process. A TCP connection is identified by the 4-tuple (src IP, src port, dst IP, dst port) — which is why one server on port 443 serves thousands of simultaneous clients. In code: listen() creates the listening socket, each accept() returns a socket dedicated to one client.
  • NAT: your machine at 192.168.x.x is not routable on the Internet. The router rewrites outgoing source IP and port to its public IP and remembers the mapping to route replies back. Consequences: several machines share one public IP, and a server behind NAT is unreachable from outside without port forwarding — hence the traversal techniques (STUN/TURN) used by WebRTC.
  • Latency vs bandwidth: bandwidth is the width of the pipe (MB/s), latency is the time of a round trip (ms). Loading 100 small resources is bound by latency (dozens of RTTs), not by throughput. Reflexes: reduce round trips (HTTP/2-3, batching), move data closer (CDN, cache), reuse connections (keep-alive, pools).
  • The everyday tools: ss -tlnp (who listens on which ports — the security reflex), ping (ICMP latency), traceroute (the path, hop by hop), dig (DNS), tcpdump to see packets, and curl -w to break down an HTTP request:
# Break a request's time down, stage by stage
curl -w '
DNS:        %{time_namelookup}s   # name resolution
TCP:        %{time_connect}s      # end of three-way handshake
TLS:        %{time_appconnect}s   # end of TLS handshake
TTFB:       %{time_starttransfer}s # first byte of the response
Total:      %{time_total}s
' -o /dev/null -s https://api.example.com/health

# Reading it: TCP - DNS ≈ 1 RTT; TLS - TCP ≈ encryption cost;
# TTFB - TLS ≈ SERVER-SIDE compute time.
# If Total explodes but TTFB is fine → throughput/size problem,
# if TTFB is bad → slow server or too many RTTs.

💡 The diagnostic reflex — “the API is slow” means nothing until you’ve separated DNS / connect / TLS / server / transfer. curl -w does that separation in one command: it’s the best possible answer to “how would you debug this?”.

In an interview

“Explain the three-way handshake.” — SYN (the client proposes its initial sequence number), SYN-ACK (the server acknowledges and proposes its own), ACK (the client confirms). Both sides have synchronized sequence numbers: the connection is established, at the cost of one RTT. Bonus: mention that TLS adds its own handshake on top, and that QUIC merges the two.

“TCP vs UDP, which do you pick?” — TCP whenever exactness is required: HTTP/1-2, databases, mail, transfers. UDP when freshness beats completeness (games, voice, video), when the exchange is tiny (DNS), or when you rebuild your own transport on top (QUIC). The hidden question: “do you know that reliability has a cost?”

TCPUDP
ConnectionYes (handshake, 1 RTT)No
Order / reliabilityGuaranteed (seq + ACK + retransmit)None
Congestion controlYesNo (up to the application)
Header20+ bytes8 bytes
UsesHTTP/1-2, DB, SSH, mailDNS, games, VoIP, QUIC/HTTP-3

“What happens when a packet is lost?” — In TCP: the receiver acknowledges the last contiguous byte received; the sender retransmits on timeout or triple duplicate ACK, and congestion control cuts the rate. In UDP: nothing — the datagram is gone, period; the application decides whether it deserves a resend.

“Can a machine behind NAT receive an incoming connection?” — Not spontaneously: NAT only routes replies to outgoing flows it has memorized. You need configured port forwarding, or traversal techniques (STUN to discover your public address, TURN as a relay) — exactly what WebRTC does.

“Why doesn’t more bandwidth speed up my API?” — Because a small request’s time is dominated by round trips: DNS + TCP handshake + TLS + request ≈ 3-4 RTTs before the first byte. At 80 ms RTT, that’s an incompressible 300 ms whatever the throughput. Solutions: keep-alive, HTTP/2-3, CDN, closer regions.

Pitfalls & misconceptions

⚠️ “UDP is unreliable, therefore unusable” — wrong: “unreliable” means the transport layer doesn’t retransmit, not that packets get lost en masse. On a decent network, nearly everything arrives. QUIC — hence HTTP/3, hence a huge share of the web — runs on UDP with reliability rebuilt on top.

  • “TCP guarantees delivery” — TCP guarantees order and integrity of what arrives, and retransmits as long as the connection lives. If the cable is cut, nothing is delivered: the application must handle timeouts and reconnections.
  • Confusing latency and bandwidth: “we have fiber, why is it slow?” — because 40 sequential requests × 50 ms RTT = 2 s, fiber or not.
  • A failing ping ≠ service down: ping tests ICMP, not your TCP port. Many hosts filter ICMP. Test the actual service: curl or nc -zv host 443.
  • Forgetting that ports < 1024 require privileges on Linux — hence apps listening on 3000/8080 behind a reverse proxy that holds 80/443.
  • ss -tlnp before any “connection refused” debugging: if nothing listens on the port, there’s no point looking further into the network.

Going further

S'entraîner sur ce sujet → Practice this topic →