GitHub avatar

Fox's Blog

How Machines Talk to Each Other: An Overview from TCP to mTLS

Why TCP, UDP, TLS, mTLS, HTTP, and WebSocket are not competing alternatives but stacked layers; a hierarchical overview of machine-to-machine communication, from raw transport to mutual authentication.

The problem: too many acronyms, not enough hierarchy

TCP, UDP, TLS, mTLS, WebSocket, HTTP, HTTPS, gRPC, QUIC; most resources covering them present them as a flat list of interchangeable options, "pick based on the use case." In reality they are not on the same level: some are transport protocols, others are security layers wrapping around transport, and others still are application protocols built on top of the first two. Understanding the hierarchy means understanding why you never "choose" between TCP and TLS: you choose TCP, then you decide whether to put TLS on top.

This article rebuilds that hierarchy layer by layer, from raw transport to mutual authentication, with for each level: what it guarantees, what it does not guarantee, and when to settle for it.

Level 1: transport (TCP vs UDP)

Everything starts here. TCP and UDP are the two main protocols of the Transport layer (Layer 4) of the OSI model. Their role is identical: carrying a data stream between two applications running on different machines. Yet their way of doing it is radically different.

It matters to understand that IP (Internet Protocol), at the Network layer (Layer 3), only routes packets from one host to another. It guarantees neither their arrival, their order, nor even their uniqueness. Routers just make independent routing decisions for each packet.

It is precisely that absence of guarantees that TCP compensates for, while UDP deliberately chooses to add nothing to stay extremely light.

TCP: reliability first

TCP (Transmission Control Protocol) is a connection-oriented protocol. Before exchanging a single byte of data, both machines must establish a logical connection.

That connection is created through the famous Three-Way Handshake:


Client                           Server
SYN ---------------------------->
        <--------------------- SYN + ACK
ACK ---------------------------->
Connection established

Each step has a precise goal:

  • SYN: the client announces it wants to open a connection and provides an initial sequence number (ISN).
  • SYN-ACK: the server accepts the connection, acknowledges the SYN, and in turn provides its own sequence number.
  • ACK: the client confirms receipt of the server's info.

From then on, both machines know the connection state and can start exchanging data.

Sequence numbers

TCP does not see data as a succession of packets, but as a continuous byte stream.

Every sent byte has a sequence number.

Example:

Message:

Bonjour

B = byte 0
o = byte 1
n = byte 2
...

If a segment holding bytes 1000 to 1499 is lost in transit, the receiver can detect exactly what is missing.

The sender retransmits only that portion.

That granularity is one of the reasons TCP is robust.

Acknowledgments (ACK)

After receiving data, the recipient sends an ACK (Acknowledgment).

Contrary to what people often imagine, an ACK does not mean:

"I received that packet"

It rather means:

"I received all bytes up to number X."

For example:

Client sends:

0 → 999

Server replies:

ACK = 1000

That means:

"Everything before byte 1000 arrived fine."

That mechanism acknowledges several segments at once (cumulative acknowledgments), reducing the number of control packets.

Retransmissions

If an ACK never arrives, TCP assumes the segment is lost.

It retransmits it automatically.

The retransmission delay (Retransmission Timeout – RTO) is not fixed.

TCP continuously measures round-trip time (RTT) via received ACKs and dynamically computes the RTO to avoid useless retransmissions.

Modern implementations also use mechanisms like Fast Retransmit: when a sender receives several duplicate ACKs (usually three), it deduces an intermediate segment was lost and resends it immediately, without waiting for the timer to expire.

Packet reordering

The Internet absolutely does not guarantee two packets take the same path.

Example:

Packet 1
Paris
  ↓
London
  ↓
New York

Packet 2
Paris
  ↓
Frankfurt
  ↓
Chicago
  ↓
New York

The second packet may arrive before the first.

TCP then temporarily stores out-of-order received segments in a buffer (reassembly buffer), then reassembles them before delivering to the application.

For the application, everything looks like it arrives perfectly in order.

Flow control

A connection does not depend only on the network.

The receiver also has limited memory capacity.

If it receives faster than it can process data, its buffers end up saturating.

TCP solves that with a sliding window.

The receiver indicates in each ACK:

Window = 32768 bytes

That means:

"You can send me up to 32 KB more."

If that window drops to zero:

Window = 0

The sender temporarily suspends transmissions until the receiver announces a new available window.

That mechanism is Flow Control and stops a fast host from flooding a slower host.

Congestion control

Even if the receiver can absorb the data, the network itself can get saturated.

Routers have limited queues.

When they overflow, packets get dropped.

TCP interprets losses as a sign of congestion and automatically adapts its throughput with a congestion window (cwnd).

Modern algorithms (like Reno, CUBIC, or BBR, depending on operating systems) tune that window to find a balance between max throughput and network stability.

Early TCP versions mostly used two mechanisms:

  • Slow Start: exponential throughput ramp until congestion is detected.
  • Congestion Avoidance: then more cautious growth, usually linear.

That permanent adaptation is one of the reasons TCP stays performant despite varying network quality.

Connection teardown

Unlike UDP, a TCP connection also has a clean teardown.

Each end closes its own stream independently with the FIN flag.

A full teardown usually takes four exchanges:

FIN
ACK
FIN
ACK

That procedure guarantees all in-flight data was properly delivered before the connection is destroyed.

UDP: maximum simplicity

UDP (User Datagram Protocol) adopts the opposite philosophy.

It is connectionless.

There is:

  • no handshake;
  • no sequence numbers;
  • no acknowledgments;
  • no retransmissions;
  • no flow control;
  • no congestion control.

Each message is simply wrapped in an independent datagram, sent to the network, then forgotten by the sender.

Application → UDP Datagram → IP → Internet

The protocol keeps no state between two sends.

Each datagram is totally independent of the previous ones.

Data integrity

Although UDP guarantees neither delivery nor order, it still protects data integrity with a checksum.

On receipt, the checksum is recomputed.

  • If the values match, the datagram is accepted.
  • Otherwise, it is immediately rejected.

So UDP detects corrupted data, but never tries to recover it.

Why is UDP so fast?

The UDP header is only 8 bytes, versus a minimum of 20 bytes for TCP (not counting options like timestamps, SACK, or Window Scaling).

With no connection maintained, the OS does not have to track each exchange's state, which also reduces memory use and processing cost.

The application gets the data almost as soon as it arrives, without waiting for potential retransmissions.

When losing data is preferable

The core idea is simple:

Old information can be worth less than lost information.

Take a VoIP conversation.

Each packet carries about 20 ms of voice.

If a packet is lost, retransmitting it would often take longer than those 20 ms.

By the time it arrived, the conversation would already have moved on.

Most applications prefer masking the loss (interpolation, silence, error correction) over waiting for the retransmission.

The same reasoning applies to:

  • real-time multiplayer games;
  • video streaming;
  • telemetry streams;
  • IoT sensors;
  • GPS position data.

A recent value is almost always more useful than an old, perfectly reliable value.

Level 2: encryption, TLS

TLS (Transport Layer Security, successor to SSL) does not replace TCP, it adds on top. Concretely, TLS establishes a normal TCP connection, then negotiates an encrypted session inside: certificate exchange, agreement on an encryption algorithm, session key derivation. Everything transiting afterward is encrypted and authenticated.

Three distinct guarantees, often confused:

  • Confidentiality: nobody but the two parties can read the content.
  • Integrity: any alteration of data in transit is detected.
  • Authentication: but in classic TLS, one-way: the client verifies the server really is who it claims to be (via its certificate, signed by a trusted authority), but the server verifies nothing about the client's identity. That's exactly the HTTPS model when you visit a site: the browser authenticates the site, the site does not authenticate you (user authentication goes through a separate mechanism, session cookie, token).

TLS 1.3 (the current recommended version) cut the handshake to a single round trip in the common case, versus two for TLS 1.2, which noticeably reduces connection latency.

Level 2b: mTLS -- authentication becomes mutual

mTLS (mutual TLS) is TLS with an extra constraint: the server also requires a client certificate, and verifies it. Both parties prove their identity via a certificate signed by a common trusted authority.

It is the natural mechanism for service-to-service communication in a distributed architecture: where classic HTTPS is enough for a browser talking to a public server, mTLS answers a different question; how does an internal service know it is really talking to another authorized internal service, and not an attacker who landed on the network?

Client                                          Server
  │──── ClientHello ─────────────────────────────▶│
  │◀─── ServerHello + server certificate ──────────│
  │──── verify server certificate ─────────────────│
  │──── send ITS OWN client certificate ──────────▶│
  │◀─── verify client certificate ─────────────────│
  │──── session keys derived, encrypted channel ──▶│

The mTLS tradeoff is operational: you need an internal certificate authority (CA), a mechanism to distribute certificates to each service, and a rotation/revocation strategy. In a single-machine environment with few services, it is sometimes more complexity than benefit -- mTLS becomes necessary once inter-service traffic crosses a network you don't fully control (multiple hosts, multi-tenant cloud), or as soon as you want a zero trust style policy, where no service is implicitly trustworthy just because it is "inside" the network.

Level 3: application protocols on top of TCP+TLS

Once transport and encryption are in place, what remains is how to structure exchanges. That's the role of application protocols.

HTTP / HTTPS

HTTP is a request-response protocol: the client opens a connection (or reuses one, with keep-alive), sends a request, waits for a response, the connection can then close or be reused. HTTPS is simply HTTP over TLS -- the S changes nothing about the protocol's semantics, only that transport is encrypted.

The request-response model has a structural limit: the server can never speak first. It can only answer what the client asks. For frequent polling (checking "anything new?" every second), it works but wastes resources -- each request recreates protocol overhead for, most of the time, nothing new to announce.

WebSocket (WS / WSS)

WebSocket answers exactly that limit. The connection starts as a classic HTTP request (with an Upgrade: websocket header), but once the handshake is accepted, the underlying TCP connection is no longer an HTTP request-response channel -- it becomes a full-duplex bidirectional channel where client and server can send messages at any time, without having to re-emit a request-response cycle on every exchange.

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

WSS is simply WebSocket over TLS, exactly like HTTPS is HTTP over TLS. It is the protocol of choice for anything needing real-time server push -- chat, notifications, trading feeds, game events -- without wanting to manage a binary protocol over raw TCP yourself.

gRPC

Less known outside the microservices world but central to service-to-service communication: gRPC builds on HTTP/2 (so TCP + optional TLS), serializes messages in Protocol Buffers (binary, typed, compact -- unlike the JSON text of most REST APIs), and natively allows bidirectional streaming thanks to HTTP/2 multiplexing (several logical streams over a single TCP connection, without the head-of-line blocking that several sequential HTTP/1.1 requests would have).

QUIC / HTTP3

QUIC changes the game by starting from UDP rather than TCP at the transport level, while reimplementing on top the reliability guarantees TCP offered natively - but stream by stream rather than globally, which eliminates transport-level head-of-line blocking (a lost packet on one stream no longer blocks the other streams of the same connection). TLS 1.3 is integrated directly into QUIC rather than added on top, which further reduces handshake latency. HTTP/3 is HTTP over QUIC.

Overview: where each protocol sits

Layer / Protocols / Role: Transport: TCP, UDP (moving bytes, reliably or not). Next-gen transport: QUIC (UDP + per-stream reliability + integrated TLS). Security: TLS, mTLS (encryption, integrity, uni- or mutual authentication). Application: HTTP/HTTPS, WS/WSS, gRPC (structuring exchanges: request-response, bidirectional, typed RPC).

A concrete example to fix ideas: a microservices architecture with a web dashboard and internal services could reasonably combine HTTPS (dashboard ↔ public API, one-way authentication enough on the browser side), mTLS (service ↔ service internally, mutual authentication needed), and WSS (real-time notifications pushed to the dashboard) -- three different application protocols, all built on the same TCP + TLS base.

How to pick, in practice

Three questions are usually enough to decide:

  1. Do I need reliability and order, or does data freshness win over guaranteed delivery? → TCP if yes, UDP if no (or QUIC to get both at once through a different tradeoff).
  2. Must the server be able to initiate messages, or does the client always ask first? → WebSocket/gRPC streaming if the server must push, plain HTTP otherwise.
  3. Must both parties mutually prove their identity, or does only one need verifying? → mTLS for service-to-service in a zero-trust environment, plain TLS for a classic public client.

Operational complexity grows with each added layer: bare TCP has no infrastructure to manage, TLS needs certificates, mTLS needs a CA and a rotation strategy, gRPC needs a shared Protobuf schema definition. The right reflex is to climb in complexity only when the layer below shows a concrete limit, not in anticipation.

Comment les machines se parlent : un tour d'horizon de TCP à mTLS

Pourquoi TCP, UDP, TLS, mTLS, HTTP et WebSocket ne sont pas des alternatives concurrentes mais des couches empilées; un tour d'horizon hiérarchique de la communication machine à machine, du transport brut à l'authentification mutuelle.

Le problème : trop de sigles, pas assez de hiérarchie

TCP, UDP, TLS, mTLS, WebSocket, HTTP, HTTPS, gRPC, QUIC; la plupart des ressources qui en parlent les présentent comme une liste plate d'options interchangeables, "à choisir selon le cas d'usage". En réalité ils ne sont pas sur le même plan : certains sont des protocoles de transport, d'autres des couches de sécurité qui s'enroulent autour du transport, d'autres encore des protocoles applicatifs qui s'appuient sur les deux premiers. Comprendre la hiérarchie, c'est comprendre pourquoi on ne "choisit" jamais entre TCP et TLS: on choisit TCP, puis on décide si on met TLS par-dessus.

Cet article reconstruit cette hiérarchie couche par couche, du transport brut jusqu'à l'authentification mutuelle, avec pour chaque niveau : ce qu'il garantit, ce qu'il ne garantit pas, et quand s'en contenter.

Niveau 1 : le transport (TCP contre UDP)

Tout commence ici. TCP et UDP sont les deux principaux protocoles de la couche Transport (Layer 4) du modèle OSI. Leur rôle est identique : transporter un flux de données entre deux applications exécutées sur des machines différentes. Pourtant, leur manière d'y parvenir est radicalement différente.

Il est important de comprendre qu'IP (Internet Protocol), situé à la couche réseau (Layer 3), ne fait qu'acheminer des paquets d'un hôte à un autre. Il ne garantit ni leur arrivée, ni leur ordre, ni même leur unicité. Les routeurs prennent simplement des décisions de routage indépendantes pour chaque paquet.

C'est précisément cette absence de garanties que TCP vient compenser, tandis qu'UDP choisit délibérément de ne rien ajouter afin de rester extrêmement léger.

TCP : la fiabilité avant tout

TCP (Transmission Control Protocol) est un protocole orienté connexion (connection-oriented). Avant d'échanger le moindre octet de données, les deux machines doivent établir une connexion logique.

Cette connexion est créée grâce au célèbre Three-Way Handshake :


Client                           Serveur
SYN ---------------------------->
        <--------------------- SYN + ACK
ACK ----------------------------> 
Connexion établie

Chaque étape possède un objectif précis :

  • SYN : le client annonce qu'il souhaite ouvrir une connexion et fournit un premier numéro de séquence (Initial Sequence Number - ISN).

  • SYN-ACK : le serveur accepte la connexion, accuse réception du SYN et fournit à son tour son propre numéro de séquence.

  • ACK : le client confirme la réception des informations du serveur.

À partir de ce moment, les deux machines connaissent l'état de la connexion et peuvent commencer à échanger des données.

Les numéros de séquence

TCP ne voit pas les données comme une succession de paquets, mais comme un flux continu d'octets (byte stream).

Chaque octet envoyé possède un numéro de séquence.

Exemple :

Message :

Bonjour

B = octet 0
o = octet 1
n = octet 2
...

Si un segment contenant les octets 1000 à 1499 est perdu pendant le transport, le récepteur peut détecter exactement ce qui manque.

L'émetteur retransmet uniquement cette portion.

Cette granularité est l'une des raisons de la robustesse de TCP.

Les accusés de réception (ACK)

Après réception des données, le destinataire envoie un ACK (Acknowledgment).

Contrairement à ce que l'on imagine souvent, un ACK ne signifie pas :

"J'ai reçu ce paquet"

Il signifie plutôt :

"J'ai reçu tous les octets jusqu'au numéro X."

Par exemple :

Client envoie :

0 → 999

Serveur répond :

ACK = 1000

Cela signifie :

"Tout ce qui précède l'octet 1000 est bien arrivé."

Ce mécanisme permet d'accuser réception de plusieurs segments à la fois (cumulative acknowledgments), réduisant ainsi le nombre de paquets de contrôle.

Les retransmissions

Si un ACK n'arrive jamais, TCP suppose que le segment est perdu.

Il le retransmet automatiquement.

Le délai de retransmission (Retransmission Timeout – RTO) n'est pas fixe.

TCP mesure en permanence le temps aller-retour (RTT) grâce aux ACK reçus et calcule dynamiquement le RTO afin d'éviter des retransmissions inutiles.

Les implémentations modernes utilisent également des mécanismes comme Fast Retransmit : lorsqu'un émetteur reçoit plusieurs ACK dupliqués (généralement trois), il déduit qu'un segment intermédiaire a été perdu et le renvoie immédiatement, sans attendre l'expiration du temporisateur.

Réorganisation des paquets

Internet ne garantit absolument pas que deux paquets suivent le même chemin.

Exemple :

Paquet 1
Paris
 ↓
Londres
 ↓
New York

Paquet 2
Paris
 ↓
Francfort
 ↓
Chicago
 ↓
New York

Le deuxième paquet peut arriver avant le premier.

TCP stocke alors temporairement les segments reçus hors ordre dans un tampon (reassembly buffer), puis les réassemble avant de les livrer à l'application.

Pour l'application, tout semble arriver parfaitement dans l'ordre.

Contrôle de flux

Une connexion ne dépend pas uniquement du réseau.

Le récepteur possède également une capacité mémoire limitée.

S'il reçoit plus vite qu'il ne peut traiter les données, ses buffers finissent par saturer.

TCP résout ce problème grâce à une fenêtre glissante (Sliding Window).

Le récepteur indique dans chaque ACK :

Window = 32768 octets

Cela signifie :

"Tu peux m'envoyer jusqu'à 32 Ko supplémentaires."

Si cette fenêtre tombe à zéro :

Window = 0

L'émetteur suspend temporairement les transmissions jusqu'à ce que le récepteur annonce une nouvelle fenêtre disponible.

Ce mécanisme constitue le contrôle de flux (Flow Control) et empêche qu'un hôte rapide n'inonde un hôte plus lent.

Contrôle de congestion

Même si le récepteur est capable d'absorber les données, le réseau lui-même peut devenir saturé.

Les routeurs disposent de files d'attente (queues) limitées.

Lorsqu'elles débordent, les paquets sont supprimés.

TCP interprète les pertes comme un signe de congestion et adapte automatiquement son débit grâce à une fenêtre de congestion (Congestion Window – cwnd).

Les algorithmes modernes (comme Reno, CUBIC ou BBR, selon les systèmes d'exploitation) ajustent cette fenêtre afin de trouver un équilibre entre débit maximal et stabilité du réseau.

Les premières versions de TCP utilisaient principalement deux mécanismes :

  • Slow Start : augmentation exponentielle du débit jusqu'à détecter une congestion.

  • Congestion Avoidance : croissance ensuite plus prudente, généralement linéaire.

Cette adaptation permanente est l'une des raisons pour lesquelles TCP reste performant malgré les variations de qualité du réseau.

Fermeture de connexion

Contrairement à UDP, une connexion TCP possède également une fermeture propre.

Chaque extrémité ferme indépendamment son flux grâce au drapeau FIN.

Une fermeture complète nécessite généralement quatre échanges :

FIN
ACK
FIN
ACK

Cette procédure garantit que toutes les données en transit ont bien été livrées avant la destruction de la connexion.

UDP : la simplicité maximale

UDP (User Datagram Protocol) adopte la philosophie inverse.

Il est sans connexion (connectionless).

Il n'existe :

  • aucun handshake ;

  • aucun numéro de séquence ;

  • aucun accusé de réception ;

  • aucune retransmission ;

  • aucun contrôle de flux ;

  • aucun contrôle de congestion.

Chaque message est simplement encapsulé dans un datagramme indépendant, transmis au réseau, puis oublié par l'émetteur.

Application → Datagramme UDP → IP → Internet

Le protocole ne conserve aucun état entre deux envois.

Chaque datagramme est totalement indépendant des précédents.

L'intégrité des données

Bien qu'UDP ne garantisse ni la livraison ni l'ordre, il protège tout de même l'intégrité des données grâce à un checksum.

À la réception, le checksum est recalculé.

  • Si les valeurs correspondent, le datagramme est accepté.

  • Sinon, il est immédiatement rejeté.

UDP détecte donc les données corrompues, mais ne tente jamais de les récupérer.

Pourquoi UDP est-il si rapide ?

L'en-tête UDP ne contient que 8 octets, contre un minimum de 20 octets pour TCP (sans compter les options comme les timestamps, SACK ou Window Scaling).

Aucune connexion n'étant maintenue, le système d'exploitation n'a pas à suivre l'état de chaque échange, ce qui réduit également la consommation mémoire et le coût de traitement.

L'application reçoit les données quasiment dès leur arrivée, sans attendre d'éventuelles retransmissions.

Quand perdre une donnée est préférable

L'idée fondamentale est simple :

Une information ancienne peut avoir moins de valeur qu'une information perdue.

Prenons une conversation VoIP.

Chaque paquet transporte environ 20 ms de voix.

Si un paquet est perdu, le retransmettre prendrait souvent plus de temps que ces 20 ms.

Lorsqu'il arriverait enfin, la conversation aurait déjà avancé.

La plupart des applications préfèrent alors masquer la perte (interpolation, silence, correction d'erreur) plutôt que d'attendre la retransmission.

Le même raisonnement s'applique :

  • aux jeux multijoueurs temps réel ;

  • au streaming vidéo ;

  • aux flux de télémétrie ;

  • aux capteurs IoT ;

  • aux données de position GPS.

Une valeur récente est presque toujours plus utile qu'une valeur ancienne parfaitement fiable.

Niveau 2 : le chiffrement, TLS

TLS (Transport Layer Security, successeur de SSL) ne remplace pas TCP, il s'ajoute par-dessus. Concrètement, TLS établit une connexion TCP normale, puis négocie une session chiffrée à l'intérieur : échange de certificats, accord sur un algorithme de chiffrement, dérivation de clés de session. Tout ce qui transite ensuite est chiffré et authentifié.

Trois garanties distinctes, souvent confondues :

  • Confidentialité : personne d'autre que les deux parties ne peut lire le contenu.

  • Intégrité : toute altération des données en transit est détectée.

  • Authentification : mais dans le TLS classique, à sens unique : le client vérifie que le serveur est bien celui qu'il prétend être (via son certificat, signé par une autorité de confiance), mais le serveur ne vérifie rien sur l'identité du client. C'est exactement le modèle de HTTPS quand tu visites un site : le navigateur authentifie le site, le site ne t'authentifie pas (l'authentification utilisateur passe par un mécanisme séparé, cookie de session, token).

TLS 1.3 (la version actuelle recommandée) a réduit le handshake à un seul aller-retour dans le cas courant, contre deux pour TLS 1.2, ce qui réduit sensiblement la latence de connexion.

Niveau 2bis : mTLS -- l'authentification devient mutuelle

mTLS (mutual TLS) est TLS avec une contrainte supplémentaire : le serveur exige aussi un certificat du client, et le vérifie. Les deux parties prouvent leur identité via un certificat signé par une autorité de confiance commune.

C'est le mécanisme naturel pour la communication service-à-service dans une architecture distribuée : là où HTTPS classique suffit pour qu'un navigateur parle à un serveur public, mTLS répond à une question différente; comment un service interne sait-il qu'il parle bien à un autre service interne autorisé, et pas à un attaquant qui aurait atterri sur le réseau ?

Client                                          Serveur
  │──── ClientHello ─────────────────────────────▶│
  │◀─── ServerHello + certificat serveur ──────────│
  │──── vérifie le certificat serveur ─────────────│
  │──── envoie SON PROPRE certificat client ──────▶│
  │◀─── vérifie le certificat client ───────────────│
  │──── clés de session dérivées, canal chiffré ──▶│

La contrepartie de mTLS est opérationnelle : il faut une autorité de certification (CA) interne, un mécanisme de distribution des certificats à chaque service, et une stratégie de rotation/révocation. Dans un environnement mono-machine avec peu de services, c'est parfois plus de complexité que de bénéfice -- mTLS devient nécessaire à partir du moment où le trafic inter-services traverse un réseau qu'on ne contrôle pas entièrement (plusieurs hôtes, cloud multi-tenant), ou dès qu'on veut une politique de type zero trust, où aucun service n'est implicitement digne de confiance simplement parce qu'il est "à l'intérieur" du réseau.

Niveau 3 : les protocoles applicatifs au-dessus de TCP+TLS

Une fois le transport et le chiffrement en place, reste à définir comment structurer les échanges. C'est le rôle des protocoles applicatifs.

HTTP / HTTPS

HTTP est un protocole requête-réponse : le client ouvre une connexion (ou en réutilise une, avec le keep-alive), envoie une requête, attend une réponse, la connexion peut ensuite se refermer ou être réutilisée. HTTPS, c'est simplement HTTP sur TLS -- le S ne change rien à la sémantique du protocole, uniquement au fait que le transport est chiffré.

Le modèle requête-réponse a une limite structurelle : le serveur ne peut jamais parler en premier. Il ne peut que répondre à ce que le client demande. Pour du polling fréquent (vérifier "y a-t-il du nouveau ?" toutes les secondes), ça marche mais gaspille des ressources -- chaque requête recrée du overhead protocolaire pour, la plupart du temps, ne rien avoir de nouveau à annoncer.

WebSocket (WS / WSS)

WebSocket répond exactement à cette limite. La connexion démarre comme une requête HTTP classique (avec un header Upgrade: websocket), mais une fois la poignée de main acceptée, la connexion TCP sous-jacente n'est plus un canal requête-réponse HTTP -- elle devient un canal bidirectionnel full-duplex où client et serveur peuvent envoyer des messages à tout moment, sans avoir à réémettre un cycle requête-réponse à chaque échange.

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

WSS est simplement WebSocket sur TLS, exactement comme HTTPS est HTTP sur TLS. C'est le protocole de choix pour tout ce qui nécessite du push serveur en temps réel -- chat, notifications, flux de trading, événements de jeu -- sans vouloir gérer soi-même un protocole binaire par-dessus TCP nu.

gRPC

Moins connu hors du monde microservices mais central en communication service-à-service : gRPC s'appuie sur HTTP/2 (donc TCP + TLS optionnel), sérialise les messages en Protocol Buffers (binaire, typé, compact - contrairement au JSON texte de la plupart des API REST), et permet nativement le streaming bidirectionnel grâce au multiplexage de HTTP/2 (plusieurs flux logiques sur une seule connexion TCP, sans le head-of-line blocking qu'aurait plusieurs requêtes HTTP/1.1 séquentielles).

QUIC / HTTP3

QUIC change la donne en repartant d'UDP plutôt que de TCP au niveau transport, tout en réimplémentant par-dessus les garanties de fiabilité que TCP offrait nativement - mais flux par flux plutôt que globalement, ce qui élimine le head-of-line blocking au niveau transport (un paquet perdu sur un flux ne bloque plus les autres flux de la même connexion). TLS 1.3 est intégré directement dans QUIC plutôt qu'ajouté par-dessus, ce qui réduit encore la latence de handshake. HTTP/3 est HTTP par-dessus QUIC.

Vue d'ensemble : où se situe chaque protocole

Couche Protocoles Rôle Transport TCP, UDP Faire voyager des octets, fiable ou non Transport (nouvelle génération) QUIC UDP + fiabilité par flux + TLS intégré Sécurité TLS, mTLS Chiffrement, intégrité, authentification (uni ou mutuelle) Application HTTP/HTTPS, WS/WSS, gRPC Structurer les échanges (requête-réponse, bidirectionnel, RPC typé)

Un exemple concret pour fixer les idées : une architecture microservices avec un dashboard web et des services internes pourrait raisonnablement combiner HTTPS (dashboard ↔ API publique, authentification uni-directionnelle suffisante côté navigateur), mTLS (service ↔ service en interne, authentification mutuelle nécessaire), et WSS (notifications temps réel poussées vers le dashboard) -- trois protocoles applicatifs différents, tous construits sur le même socle TCP + TLS.

Comment choisir, en pratique

Trois questions suffisent généralement à trancher :

  1. Ai-je besoin de fiabilité et d'ordre, ou la fraîcheur de la donnée prime-t-elle sur sa livraison garantie ? → TCP si oui, UDP si non (ou QUIC pour avoir les deux à la fois via un compromis différent).

  2. Le serveur doit-il pouvoir initier des messages, ou le client fait-il toujours la première demande ? → WebSocket/gRPC streaming si le serveur doit pousser, HTTP classique sinon.

  3. Les deux parties doivent-elles se prouver mutuellement leur identité, ou seule une des deux a besoin d'être vérifiée ? → mTLS pour du service-à-service en environnement zero-trust, TLS simple pour du client public classique.

La complexité opérationnelle augmente à chaque couche ajoutée, TCP nu n'a aucune infrastructure à gérer, TLS demande des certificats, mTLS demande une CA et une stratégie de rotation, gRPC demande une définition de schéma Protobuf partagée. Le bon réflexe est de ne monter en complexité que quand la couche du dessous montre une limite concrète, pas par anticipation.

机器之间怎么聊天:从 TCP 到 mTLS 一览

为什么 TCP、UDP、TLS、mTLS、HTTP 和 WebSocket 不是互相替代的选项而是叠起来的层:从裸传输到双向认证的机器通信分层 tour。

问题:缩写太多,层级太少

TCP、UDP、TLS、mTLS、WebSocket、HTTP、HTTPS、gRPC、QUIC,大多数讲它们的资料都摆成一张扁平的备选项清单,"按场景选"。实际上它们根本不在同一层:有的是传输协议,有的是包在传输外面的安全层,还有的是架在前两者之上的应用协议。看懂层级,就懂为什么你永远不在 TCP 和 TLS 之间"二选一":你先选 TCP,再决定要不要在上面加 TLS。

这篇按层重建这个体系,从裸传输一直到双向认证,每层讲:它保证什么,不保证什么,什么时候停在这层就够。

第 1 层:传输(TCP 对 UDP)

一切从这里开始。TCP 和 UDP 是 OSI 模型**传输层(Layer 4)**的两个主要协议。角色一样:在不同机器上跑的两个应用之间搬运数据流。实现方式完全相反。

要先明白 IP(Internet Protocol,网络层 Layer 3)只把包从一台主机送到另一台。不保证到,不保证顺序,不保证不重复。路由器给每个包独立做路由决策。

TCP 补的正是这些缺失的保证,UDP 则故意什么都不加,保持极致轻量。

TCP:可靠优先

TCP(Transmission Control Protocol)是面向连接(connection-oriented)协议。交换一字节数据之前,两台机器先建立逻辑连接。

连接靠著名的三次握手建起来:


Client                           Serveur
SYN ---------------------------->
        <--------------------- SYN + ACK
ACK ---------------------------->
Connexion établie

每一步目的明确:

  • SYN:客户端宣布要建连接,给出第一个序列号(Initial Sequence Number,ISN)。
  • SYN-ACK:服务器接受连接,确认收到 SYN,并给出自己的序列号。
  • ACK:客户端确认收到服务器的信息。

从这一刻起,两边都知道连接状态,可以开始传数据了。

序列号

TCP 不把数据看成一串包,而看成连续字节流(byte stream)。

每个发出的字节都有序列号。

例子:

消息:

Bonjour

B = 字节 0
o = 字节 1
n = 字节 2
...

如果带字节 1000 到 1499 的段在传输中丢了,接收方能精确知道缺哪块。

发送方只重传这一块。

这种粒度是 TCP 健壮的原因之一。

确认(ACK)

收到数据后,接收方发 ACK(Acknowledgment)。

和直觉相反,ACK 不是说:

"这个包我收到了"

而是说:

"序列号 X 之前的所有字节我都收到了。"

比如:

客户端发:

0 → 999

服务器回:

ACK = 1000

意思是:

"字节 1000 之前的东西都到了。"

这个机制一次确认多个段(cumulative acknowledgments),减少控制包数量。

重传

ACK 一直不来,TCP 就当段丢了。

自动重传。

重传超时(Retransmission Timeout,RTO)不是固定的。

TCP 靠收到的 ACK 持续测往返时间(RTT),动态算 RTO,避免无谓重传。

现代实现还有 Fast Retransmit:发送方收到多个重复 ACK(一般三个),就推断中间有个段丢了,不等定时器到期立刻重发。

包重排

Internet 绝不保证两个包走同一条路。

例子:

包 1
Paris
  ↓
Londres
  ↓
New York

包 2
Paris
  ↓
Francfort
  ↓
Chicago
  ↓
New York

第二个包可能比第一个先到。

TCP 把乱序到的段暂存在重组缓冲(reassembly buffer)里,再按序交给应用。

应用看到的永远是完美有序的。

流量控制

连接不只取决于网络。

接收方内存也有限。

收得比处理得快,缓冲就爆。

TCP 用**滑动窗口(Sliding Window)**解决。

接收方在每个 ACK 里声明:

Window = 32768 字节

意思是:

"你最多再发 32 Ko。"

窗口掉到零:

Window = 0

发送方暂停,等接收方宣布新窗口再动。

这就是流量控制(Flow Control),防止快主机淹没慢主机。

拥塞控制

接收方吃得下,网络本身也可能堵。

路由器队列(queues)有限。

满了就丢包。

TCP 把丢包读成拥塞信号,用**拥塞窗口(Congestion Window,cwnd)**自动调速。

现代算法(Reno、CUBIC、BBR,看操作系统)调这个窗口,在最高吞吐和网络稳定之间找平衡。

早期 TCP 主要两招:

  • Slow Start:指数涨速,直到发现拥塞。
  • Congestion Avoidance:之后收敛,一般线性涨。

这种永远在线的自适应,是 TCP 在各种网络质量下都稳的原因之一。

连接关闭

和 UDP 不同,TCP 连接有关闭仪式。

两端各用 FIN 标志独立关闭自己的流。

完整关闭一般要四次交换:

FIN
ACK
FIN
ACK

保证在传的数据都交付了,连接才销毁。

UDP:极简到底

UDP(User Datagram Protocol)走相反哲学。

无连接(connectionless)。

没有:

  • 握手,
  • 序列号,
  • 确认,
  • 重传,
  • 流量控制,
  • 拥塞控制。

每个消息包进独立的数据报,发出去就忘。

应用 → UDP 数据报 → IP → Internet

协议在两次发送之间不存任何状态。

每个数据报和之前发的完全独立。

数据完整性

UDP 不保证送达和顺序,但用 checksum 保完整性。

收到重算 checksum。

  • 对上就收,
  • 对不上直接扔。

UDP 能发现数据坏了,但永远不尝试恢复。

为什么 UDP 这么快?

UDP 头只有 8 字节,TCP 最少 20 字节(还不算时间戳、SACK、Window Scaling 这些选项)。

不用维持连接,操作系统不用跟踪每条交换的状态,内存占用和处理成本都下来。

应用几乎数据一到就拿到,不等可能的重传。

丢点数据反而更好

核心思想很简单:

过期信息的价值不如丢掉它。

拿 VoIP 通话说。

每包大约 20 ms 语音。

丢一包,重传回来往往超过这 20 ms。

等它到,对话早往前走了。

大多数应用宁可掩盖丢失(插值、静音、纠错)也不等重传。

同理:

  • 实时多人游戏,
  • 视频流,
  • 遥测流,
  • IoT 传感器,
  • GPS 位置数据。

新鲜的值几乎永远比完美可靠的老值有用。

第 2 层:加密,TLS

TLS(Transport Layer Security,SSL 的后继)不替代 TCP,加在上面。具体说,先建普通 TCP 连接,再在里面协商加密会话:交换证书,商定加密算法,派生会话密钥。之后走的一切都加密加防篡改。

三个经常被混在一起的保证,分开说:

  • 机密性:除双方外没人能读内容。
  • 完整性:传输中任何篡改都会被发现。
  • 认证:但经典 TLS 是单向的:客户端验证服务器确实是它声称的那台(证书由可信机构签),服务器不验证客户端是谁。这正是你逛网站时的 HTTPS 模型:浏览器认证网站,网站不认证你(用户认证走别的机制,cookie session、token)。

TLS 1.3(当前推荐版本)把握手压到常见情况一轮往返,TLS 1.2 要两轮,连接延迟明显下来。

第 2 层之二:mTLS,认证变双向

mTLS(mutual TLS)是 TLS 加一条:服务器也要客户端证书,并验证。双方都拿可信机构签的证书证明身份。

这是分布式架构里服务之间通信的天然机制:经典 HTTPS 够浏览器连公网服务,但 mTLS 回答另一个问题,内部服务怎么知道对面真是被授权的内部服务,而不是混进网络的攻击者?

Client                                          Serveur
  │──── ClientHello ─────────────────────────────▶│
  │◀─── ServerHello + 服务器证书 ──────────│
  │──── 验证服务器证书 ─────────────│
  │──── 发送自己的客户端证书 ──────▶│
  │◀─── 验证客户端证书 ───────────────│
  │──── 派生会话密钥,加密通道 ──▶│

mTLS 的代价在运维:要内部 CA,给每个服务发证书,管轮换吊销。单机几个服务时,这复杂度可能超过收益,mTLS 从流量开始走你不完全掌控的网络(多主机、多租户云),或者要 zero trust 策略("在"内网里也不默认信谁)时才必要。

第 3 层:TCP+TLS 之上的应用协议

传输和加密就位,还剩怎么组织交换。这是应用协议的活。

HTTP / HTTPS

HTTP 是请求响应协议:客户端建连接(或复用 keep-alive),发请求,等响应,连接可关可复用。HTTPS 就是跑在 TLS 上的 HTTP,S 只改传输加密,不改协议语义。

请求响应模型有个结构性局限:服务器永远不能先说话。只能答客户端问的。频繁轮询"有新的吗"能跑,但浪费资源,每个请求都带协议开销,大多数时候还没有新东西可宣布。

WebSocket(WS / WSS)

WebSocket 正好补这个缺口。连接以普通 HTTP 请求起步(带 Upgrade: websocket 头),握手一接受,底下 TCP 连接不再是请求响应通道,变成全双工双向通道,客户端服务器随时发消息,不用每交换一次重走请求响应周期。

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

WSS 就是跑在 TLS 上的 WebSocket,和 HTTPS 之于 HTTP 一样。凡要服务器实时推,聊天、通知、交易流、游戏事件,又不想在裸 TCP 上手写二进制协议,选它。

gRPC

微服务服务间通信圈外不太出名、圈内核心:gRPC 跑在 HTTP/2 上(所以 TCP + 可选 TLS),消息用 Protocol Buffers 序列化(二进制、带类型、紧凑,不像大多数 REST API 的 JSON 文本),靠 HTTP/2 多路复用原生支持双向流(一条 TCP 连接上多个逻辑流,不像串行 HTTP/1.1 请求那样队头阻塞)。

QUIC / HTTP3

QUIC 在传输层换打法:从 UDP 起步,把 TCP 原生的可靠保证在上面按流重做一遍,但按流而不是全局,消掉传输层队头阻塞(一条流丢包不再卡住同连接别的流)。TLS 1.3 直接内嵌进 QUIC,不再外挂,握手延迟再降。HTTP/3 就是跑在 QUIC 上的 HTTP。

总览:各协议坐哪层

层 协议 作用 传输 TCP、UDP 搬字节,可靠或不可靠 传输(新一代) QUIC UDP + 按流可靠 + 内嵌 TLS 安全 TLS、mTLS 加密、完整性、认证(单向或双向) 应用 HTTP/HTTPS、WS/WSS、gRPC 组织交换(请求响应、双向、类型化 RPC)

举个具体例子定住:微服务加管理后台的架构可以合理地混用 HTTPS(后台连公开 API,浏览器侧单向认证够了)、mTLS(服务连服务内部,互相认证必要)、WSS(实时通知推给后台),三种不同的应用协议,底下同一套 TCP + TLS。

实战怎么选

一般三个问题就够:

  1. 我要可靠有序,还是新鲜比送达重要? → 要可靠选 TCP,要新鲜选 UDP(或 QUIC,两边都要的折中)。
  2. 服务器要不要主动发消息,还是永远客户端先问? → 要服务器推选 WebSocket/gRPC 流,否则经典 HTTP。
  3. 双方要不要互相证明身份,还是只验一边? → 服务间 zero trust 环境选 mTLS,公开客户端经典场景 TLS 单向够了。

每加一层运维复杂度涨一截,裸 TCP 零基础设施,TLS 要证书,mTLS 要 CA 加轮换策略,gRPC 要共享 Protobuf schema 定义。好习惯是底层出现具体瓶颈再往上加,别提前加。

マシン同士はどう話すか:TCPからmTLSまでの見取り図

TCP、UDP、TLS、mTLS、HTTP、WebSocketは競合する選択肢じゃなく積み重なる層だ。素の転送から相互認証まで、機械間通信の階層的見取り図。

問題:略語が多すぎて階層がなさすぎる

TCP、UDP、TLS、mTLS、WebSocket、HTTP、HTTPS、gRPC、QUIC。これらを語る資料の大半は、平らな互換選択肢リストとして並べて「用途で選べ」って言う。実際は同じ平面にいない。転送プロトコルもあれば、転送を包む安全層もあれば、両者の上に乗るアプリケーションプロトコルもある。階層を理解することが、TCPとTLSの間で「選ぶ」ことは決してない理由の理解だ。TCPを選んで、_それから_TLSを上に乗せるか決めるんだ。

この記事はこの階層を層ごとに再構築する。素の転送から相互認証まで、各水準でこう示す。何を保証するか、何を保証しないか、いつそれで足りるかだ。

水準1:転送(TCP対UDP)

全部ここから始まる。TCPとUDPはOSIモデルの**トランスポート層(Layer 4)**の2大プロトコルだ。役割は同じだ。違うマシンで動く2つのアプリ間でデータ流を運ぶことだ。でもやり方は根本的に違う。

大事な理解として、ネットワーク層(Layer 3)のIP(Internet Protocol)はホストからホストへパケットを運ぶだけだ。到着も順序も一意性も保証しない。ルーターは各パケットに独立の経路決定をするだけだ。

この保証欠落をTCPが埋めに来て、UDPはわざと何も足さず極限まで軽く保つ。

TCP:信頼性が第一

TCP(Transmission Control Protocol)はコネクション型(connection-oriented)プロトコルだ。1バイトのデータを交換する前に、2台のマシンが論理コネクションを確立しなきゃいけない。

このコネクションは有名なスリーウェイハンドシェイクで作られる。


Client                           Serveur
SYN ---------------------------->
        <--------------------- SYN + ACK
ACK ----------------------------> 
Connexion établie

各段階に明確な目的がある。

  • SYN:クライアントがコネクションを開きたいと宣言して、最初のシーケンス番号(Initial Sequence Number - ISN)を渡す。

  • SYN-ACK:サーバーがコネクションを受けて、SYNを確認して、今度は自分のシーケンス番号を渡す。

  • ACK:クライアントがサーバー情報の受信を確認する。

ここから2台のマシンはコネクション状態を知って、データ交換を始められる。

シーケンス番号

TCPはデータをパケットの連なりじゃなく連続バイト流(byte stream)として見る。

送る各バイトにシーケンス番号がある。

例:

Message :

Bonjour

B = octet 0
o = octet 1
n = octet 2
...

1000から1499バイト目のセグメントが転送中に失われたら、受信側は正確に何が欠けたか検出できる。

送信側はその部分だけ再送する。

この粒度がTCPの頑丈さの理由の1つだ。

確認応答(ACK)

データ受信後、宛先は**ACK(Acknowledgment)**を送る。

よく想像されるのと違って、ACKの意味はこうじゃない。

「このパケットを受け取った」

むしろこうだ。

「X番までのバイトは全部受け取った」

たとえばこうだ。

Client envoie :

0 → 999

Serveur répond :

ACK = 1000

意味はこうだ。

「バイト1000より前は全部届いた」

この仕組みで複数セグメントをまとめて確認できる(cumulative acknowledgments)。制御パケット数を減らせる。

再送

ACKが来なければ、TCPはセグメントが失われたとみなす。

自動で再送する。

再送遅延(Retransmission Timeout、RTO)は固定じゃない。

TCPは受けたACKで往復時間(RTT)を常に測って、無駄な再送を避けるようRTOを動的計算する。

現代実装はFast Retransmitみたいな仕組みも使う。送信側が重複ACKを複数(だいたい3つ)受けたら、中間セグメントが失われたと推測して、タイマー切れを待たず即送り直す。

パケットの並べ替え

インターネットは2つのパケットが同じ道を通ることをまったく保証しない。

例:

Paquet 1
Paris
  ↓
Londres
  ↓
New York

Paquet 2
Paris
  ↓
Francfort
  ↓
Chicago
  ↓
New York

2つ目のパケットが先に着くことがある。

TCPは順序外で受けたセグメントをバッファ(reassembly buffer)に一時置いて、アプリに渡す前に組み立て直す。

アプリからは全部完璧な順序で届いたように見える。

フロー制御

コネクションはネットワークだけで決まらない。

受信側にも限られたメモリ容量がある。

処理できるより速く受けたらバッファが飽和する。

TCPは**スライディングウィンドウ(Sliding Window)**でこの問題を解く。

受信側は各ACKでこう示す。

Window = 32768 octets

意味はこうだ。

「あと32KBまで送っていいよ」

このウィンドウがゼロになったらこうだ。

Window = 0

送信側は受信側が新しい利用可能ウィンドウを告げるまで送信を一時止める。

この仕組みが**フロー制御(Flow Control)**で、速いホストが遅いホストを洪水にしない。

輻輳制御

受信側がデータを吸収できても、ネットワーク自体が飽和することがある。

ルーターは限られたキュー(queues)を持つ。

溢れたらパケットは捨てられる。

TCPは損失を輻輳の印と読んで、**輻輳ウィンドウ(Congestion Window、cwnd)**で送信量を自動調整する。

現代アルゴリズム(OSによるがRenoやCUBICやBBR)はこのウィンドウを調整して、最大スループットとネットワーク安定の均衡を探る。

初期のTCPは主に2仕組みを使ってた。

  • Slow Start:輻輳検出まで送信量を指数増加させる。

  • Congestion Avoidance:その後は慎重に、だいたい線形に増やす。

この常時適応が、ネットワーク品質が変わってもTCPが高性能な理由の1つだ。

コネクション終了

UDPと違ってTCPコネクションにはきれいな終了もある。

各端がFINフラグで自分の流を独立に閉じる。

完全な終了にはだいたい4往復要る。

FIN
ACK
FIN
ACK

この手順で、転送中データが全部届いてからコネクション破棄されることが保証される。

UDP:最大の単純さ

UDP(User Datagram Protocol)は逆の哲学だ。

**コネクションレス(connectionless)**だ。

存在しないものはこうだ。

  • ハンドシェイクなし。

  • シーケンス番号なし。

  • 確認応答なし。

  • 再送なし。

  • フロー制御なし。

  • 輻輳制御なし。

各メッセージは独立データグラムに包まれて、ネットワークに投げられて、送信側は忘れる。

Application → Datagramme UDP → IP → Internet

プロトコルは2回送信の間に状態を持たない。

各データグラムは前と完全独立だ。

データ完全性

UDPは配送も順序も保証しないけど、チェックサムでデータ完全性は守る。

受信時にチェックサムを再計算する。

  • 値が合えばデータグラム受理。

  • 合わなければ即棄却。

つまりUDPは壊れたデータを検出するけど、取り戻そうとは絶対しない。

なぜUDPは速いのか

UDPヘッダは8バイトだけで、TCPは最低20バイトだ(タイムスタンプやSACKやWindow Scalingみたいなオプション別)。

コネクションを維持しないので、OSは各交換の状態を追わなくていい。メモリ消費も処理コストも減る。

アプリはデータが着いたらほぼ即受け取る。再送待ちなしだ。

データを失う方がましなとき

根本発想は単純だ。

古い情報は失われた情報より価値が低いことがある。

VoIP通話を取ろう。

各パケットは約20msの声を運ぶ。

パケットが失われたら、再送にはその20msより長くかかることが多い。

ようやく届いた頃には通話は先に進んでる。

だから大半アプリは再送待ちより損失隠し(補間、無音、誤り訂正)を選ぶ。

同じ理屈がこうにも当てはまる。

  • リアルタイムマルチプレイゲーム。

  • 動画ストリーミング。

  • テレメトリ流。

  • IoTセンサー。

  • GPS位置データ。

新しい値は、完全信頼の古い値よりほぼいつも有用だ。

水準2:暗号化、TLS

TLS(Transport Layer Security、SSLの後継)はTCPを置き換えない。上に足される。具体的にはTLSは普通のTCPコネクションを確立してから、中に暗号化セッションを交渉する。証明書交換、暗号アルゴリズム合意、セッション鍵導出だ。その後流れるものは全部暗号化されて認証される。

よく混同される3つの別保証だ。

  • 機密性:両当事者以外は内容を読めない。

  • 完全性:転送中の改変は全部検出される。

  • 認証:でも古典TLSでは片方向だ。クライアントはサーバーが名乗る相手か検証する(信頼できる認証局署名の証明書経由)が、サーバーはクライアント身分を何も検証しない。サイト訪問時のHTTPSモデルがまさにこれだ。ブラウザはサイトを認証する。サイトは君を認証しない(ユーザー認証は別仕組み、セッションクッキーやトークンを通る)。

TLS 1.3(現行推奨版)はハンドシェイクを通常1往復に減らした。TLS 1.2の2回からだ。コネクション遅延がかなり減る。

水準2bis:mTLS。認証が相互になる

mTLS(mutual TLS)は追加制約付きTLSだ。サーバーもクライアント証明書を要求して検証する。両者が共通の信頼認証局署名の証明書で身分を証明する。

分散アーキテクチャのサービス間通信の自然な仕組みだ。古典HTTPSが公開サーバーと話すブラウザに足りるのに対し、mTLSは違う問いに答える。内部サービスはどうやって、許可された別の内部サービスと話してると知るのか。ネットワークに入り込んだ攻撃者じゃないと。

Client                                          Serveur
  │──── ClientHello ─────────────────────────────▶│
  │◀─── ServerHello + certificat serveur ──────────│
  │──── vérifie le certificat serveur ─────────────│
  │──── envoie SON PROPRE certificat client ──────▶│
  │◀─── vérifie le certificat client ───────────────│
  │──── clés de session dérivées, canal chiffré ──▶│

mTLSの代償は運用だ。内部認証局(CA)が要る。各サービスへの証明書配布仕組みが要る。ローテーションや失効の戦略が要る。サービスが少ない単一マシン環境では複雑さが利益を上回ることもある。mTLSが必要になるのは、サービス間トラフィックが完全管理できない網を通るようになってからだ(複数ホスト、マルチテナントクラウド)。あるいはゼロトラスト型方針が欲しいときだ。網の「内側」にいるだけでサービスが暗黙に信頼に足りることはない、というやつだ。

水準3:TCPとTLSの上のアプリケーションプロトコル

転送と暗号化ができたら、残りは交換をどう構造化するかだ。アプリケーションプロトコルの役割だ。

HTTP / HTTPS

HTTPはリクエストレスポンス型プロトコルだ。クライアントがコネクションを開いて(keep-aliveで再利用して)、リクエストを送って、応答を待つ。コネクションはその後閉じても再利用してもいい。HTTPSはTLS上のHTTPに過ぎない。Sはプロトコル意味を何も変えない。転送が暗号化されるってだけだ。

リクエストレスポンス型モデルには構造的限界がある。サーバーは決して先に話せない。クライアントの求めに答えるだけだ。頻繁ポーリング(毎秒「新着ある」確認)には動くけど資源を無駄にする。新着がないことが大半なのに、各リクエストがプロトコルオーバーヘッドを作り直すからね。

WebSocket(WS / WSS)

WebSocketはまさにこの限界に答える。コネクションは古典HTTPリクエストとして始まる(Upgrade: websocketヘッダー付き)。でもハンドシェイクが受け入れられたら、下のTCPコネクションはもうHTTPリクエストレスポンス型チャネルじゃない。クライアントもサーバーもいつでもメッセージを送れる双方向全二重チャネルになる。各交換でリクエストレスポンス周期を出し直さなくていい。

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

WSSはTLS上のWebSocketに過ぎない。HTTPSがTLS上のHTTPなのとまったく同じだ。サーバー側プッシュのリアルタイムが必要なもの全部の選択肢プロトコルだ。チャット、通知、取引流、ゲームイベントなど。素のTCP上に自前バイナリプロトコルを管理したくない場合だね。

gRPC

マイクロサービス界隈外では知名度が低いけどサービス間通信の中心だ。gRPCはHTTP/2の上に乗る(つまりTCPと任意TLS)。メッセージをProtocol Buffersで直列化する(大半REST APIのテキストJSONと違ってバイナリで型付きでコンパクト)。HTTP/2の多重化のおかげで生来の双方向ストリーミングができる(単一TCPコネクション上の複数論理流。HTTP/1.1逐次リクエスト複数みたいなhead-of-line blockingなし)。

QUIC / HTTP3

QUICは転送水準でUDPから出直して流れを変える。それでいてTCP本来の信頼保証を上に再実装する。でも全体じゃなく流ごとにだ。これで転送水準のhead-of-line blockingを消す(1つの流のパケット損失が同じコネクションの他流を止めない)。TLS 1.3は上に足すんじゃなくQUICに直接統合されてて、ハンドシェイク遅延をさらに減らす。HTTP/3はQUIC上のHTTPだ。

全体図:各プロトコルの位置

層 プロトコル 役割 転送 TCP、UDP バイトを運ぶ、信頼ありかなしか 転送(新世代) QUIC UDPと流ごと信頼とTLS統合 安全 TLS、mTLS 暗号化、完全性、認証(片方向か相互) 応用 HTTP/HTTPS、WS/WSS、gRPC 交換の構造化(リクレス、双方向、型付きRPC)

具体例で固めよう。ウェブダッシュボードと内部サービスのあるマイクロサービスアーキテクチャなら、HTTPS(ダッシュボードと公開API間。ブラウザ側は片方向認証で十分)、mTLS(内部のサービス間。相互認証が必要)、WSS(ダッシュボードへのリアルタイム通知プッシュ)と組み合わせるのが合理的だ。違う応用プロトコル3つで、土台は全部同じTCPとTLSだ。

実際どう選ぶか

3つの問いがあればだいたい決まる。

  1. 信頼と順序が要るか。データ鮮度が保証配送より勝つか。 → 前者ならTCP、後者ならUDP(両方欲しければQUICで違う妥協)。

  2. サーバーがメッセージを始められなきゃいけないか。クライアントがいつも先に求めるか。 → サーバーが押すならWebSocketやgRPCストリーミング、そうじゃないなら古典HTTP。

  3. 両者が互いに身分を証明し合わなきゃいけないか。片方検証でいいか。 → ゼロトラスト環境のサービス間ならmTLS、古典公開クライアントなら単純TLS。

足す層ごとに運用複雑さは上がる。素のTCPは管理土台ゼロ、TLSは証明書が要る、mTLSはCAとローテーション戦略が要る、gRPCは共有Protobufスキーマ定義が要る。正しい反射は、下の層が具体的な限界を見せたときだけ複雑さを上げることで、先回りじゃない。

기계들이 대화하는 방법: TCP에서 mTLS까지 둘러보기

TCP, UDP, TLS, mTLS, HTTP, WebSocket이 경쟁하는 대안이 아니라 쌓이는 층인 이유. 날것 전송에서 상호 인증까지, 기계 대 기계 통신을 층별로 둘러봐요.

문제: 약어는 많고 위계는 부족해요

TCP, UDP, TLS, mTLS, WebSocket, HTTP, HTTPS, gRPC, QUIC. 이들을 다루는 대부분의 자료는 "쓰임에 따라 고르라"며 평평하고 바꿔 쓸 수 있는 선택지 목록으로 보여줘요. 실제로는 같은 층에 있지 않아요. 어떤 것은 전송 프로토콜이고, 어떤 것은 전송을 감싸는 보안 층이고, 또 어떤 것은 앞의 둘 위에 얹는 애플리케이션 프로토콜이에요. 위계를 이해하는 것이 TCP와 TLS 사이에서 "고르지" 않는 이유를 이해하는 거예요. TCP를 고른 뒤 위에 TLS를 올릴지 정해요.

이 글은 그 위계를 층마다 다시 쌓아요. 날것 전송에서 상호 인증까지요. 각 수준마다 보장하는 것과 보장하지 않는 것, 그리고 언제 그 수준으로 충분한지 함께요.

수준 1: 전송 (TCP 대 UDP)

모든 것이 여기서 시작해요. TCP와 UDP는 OSI 모델의 전송 (4계층) 프로토콜 두 가지예요. 역할은 같아요. 서로 다른 기기에서 돌아가는 두 애플리케이션 사이에 자료 흐름을 나르는 거예요. 그런데 해내는 방식이 근본적으로 달라요.

네트워크 계층(3계층)의 IP(Internet Protocol)는 패킷을 한 호스트에서 다른 호스트로 나를 뿐임을 이해하는 것이 중요해요. 도착도 순서도 유일함도 보장하지 않아요. 라우터는 각 패킷마다 독립적인 라우팅 결정을 내릴 뿐이에요.

보장 부재를 메우는 것이 바로 TCP이고, UDP는 극도로 가볍게 남으려고 일부러 아무것도 더하지 않아요.

TCP: 믿을 수 있음이 먼저

TCP(Transmission Control Protocol)는 연결 지향(connection-oriented) 프로토콜이에요. 자료 1바이트를 주고받기 전에 두 기기가 논리적 연결을 맺어야 해요.

이 연결은 유명한 Three-Way Handshake로 만들어져요.


Client                           Serveur
SYN ---------------------------->
        <--------------------- SYN + ACK
ACK ---------------------------->
Connexion établie

각 단계에는 정확한 목표가 있어요.

  • SYN: 클라이언트가 연결을 열고 싶다고 알리고 첫 순서 번호(Initial Sequence Number - ISN)를 줘요.

  • SYN-ACK: 서버가 연결을 받아들이고 SYN을 확인하며 차례로 자신의 순서 번호를 줘요.

  • ACK: 클라이언트가 서버 정보 수신을 확인해요.

이 순간부터 두 기기는 연결 상태를 알고 자료를 주고받기 시작할 수 있어요.

순서 번호

TCP는 자료를 패킷 연속이 아니라 끊기지 않는 바이트 흐름(byte stream)으로 봐요.

보내는 각 바이트에 순서 번호가 있어요.

예시:

메시지:

Bonjour

B = 바이트 0
o = 바이트 1
n = 바이트 2
...

1000번에서 1499번 바이트가 든 세그먼트가 전송 중에 사라지면 수신자가 정확히 무엇이 없는지 감지할 수 있어요.

송신자는 그 부분만 다시 보내요.

이 세밀함이 TCP 강건함의 이유 중 하나예요.

수신 확인 (ACK)

자료를 받은 뒤 수신자가 **ACK (Acknowledgment)**를 보내요.

흔히 생각하는 것과 달리 ACK의 뜻은 이것이 아니에요.

"이 패킷을 받았어요"

오히려 뜻은요.

"X번까지의 바이트를 모두 받았어요."

예를 들어요.

클라이언트가 보내요:

0 → 999

서버가 답해요:

ACK = 1000

뜻은요.

"1000번 바이트 앞의 모든 것이 잘 도착했어요."

이 구조로 여러 세그먼트를 한 번에 확인(cumulative acknowledgments)해서 제어 패킷 수를 줄여요.

재전송

ACK이 절대 오지 않으면 TCP는 세그먼트가 사라졌다고 봐요.

자동으로 다시 보내요.

재전송 대기 시간(Retransmission Timeout – RTO)은 고정되지 않아요.

받은 ACK로 TCP는 왕복 시간(RTT)을 계속 재고, 쓸데없는 재전송을 피하려고 RTO를 동적으로 계산해요.

현대 구현은 Fast Retransmit 같은 구조도 써요. 송신자가 중복 ACK를 여러 번(보통 셋) 받으면 중간 세그먼트 하나가 사라졌다고 보고, 타이머 만료를 기다리지 않고 바로 다시 보내요.

패킷 재정렬

두 패킷이 같은 길을 따른다고 인터넷은 전혀 보장하지 않아요.

예시:

패킷 1
Paris
  ↓
Londres
  ↓
New York

패킷 2
Paris
  ↓
Francfort
  ↓
Chicago
  ↓
New York

두 번째 패킷이 첫 번째보다 먼저 도착할 수 있어요.

그러면 TCP가 순서 밖에 도착한 세그먼트들을 버퍼(reassembly buffer)에 잠시 저장했다가 애플리케이션에 건네기 전에 다시 조립해요.

애플리케이션 보기에는 모든 것이 완벽한 순서로 도착하는 것처럼 보여요.

흐름 제어

연결은 네트워크에만 달려 있지 않아요.

수신자도 메모리 용량이 제한되어 있어요.

처리할 수 있는 것보다 빨리 받으면 버퍼가 결국 포화돼요.

TCP는 **슬라이딩 윈도 (Sliding Window)**로 이 문제를 풀어요.

수신자는 각 ACK에 이렇게 알려줘요.

Window = 32768 octets

뜻은요.

"32KB까지 더 보내도 돼요."

이 창이 0이 되면요.

Window = 0

송신자는 수신자가 새 가용 창을 알릴 때까지 전송을 잠시 멈춰요.

이 구조가 **흐름 제어 (Flow Control)**이고, 빠른 호스트가 느린 호스트를 넘치게 하는 것을 막아요.

혼잡 제어

수신자가 자료를 받아낼 수 있어도 네트워크 자체가 포화될 수 있어요.

라우터에는 제한된 대기열(queues)이 있어요.

넘치면 패킷이 버려져요.

TCP는 손실을 혼잡 신호로 보고 **혼잡 윈도 (Congestion Window – cwnd)**로 속도를 자동으로 맞춰요.

현대 알고리즘(운영체제에 따라 Reno, CUBIC, BBR)이 최대 속도와 네트워크 안정 사이 균형을 찾으려고 이 창을 조정해요.

초기 TCP 버전은 주로 두 가지 구조를 썼어요.

  • Slow Start: 혼잡을 감지할 때까지 속도를 지수적으로 올려요.

  • Congestion Avoidance: 그 뒤에는 더 조심스럽게, 보통 선형으로 키워요.

이 영속 적응이 네트워크 품질 변화에도 TCP가 성능을 유지하는 이유 중 하나예요.

연결 닫기

UDP와 달리 TCP 연결에는 깔끔한 닫기도 있어요.

각 끝이 FIN 깃발로 자기 흐름을 독립적으로 닫아요.

완전한 닫기에는 보통 네 번 교환이 필요해요.

FIN
ACK
FIN
ACK

이 절차는 연결을 없애기 전에 전송 중 자료가 모두 잘 배달됐음을 보장해요.

UDP: 최대한 단순

UDP(User Datagram Protocol)는 반대 철학을 써요.

**비연결형 (connectionless)**이에요.

존재하지 않아요.

  • 핸드셰이크 없음;

  • 순서 번호 없음;

  • 수신 확인 없음;

  • 재전송 없음;

  • 흐름 제어 없음;

  • 혼잡 제어 없음.

각 메시지는 독립 데이터그램에 그냥 캡슐화되어 네트워크로 보내지고, 송신자는 잊어버려요.

Application → Datagramme UDP → IP → Internet

프로토콜은 두 번 보내기 사이에 상태를 유지하지 않아요.

각 데이터그램은 앞선 것들과 완전히 독립적이에요.

자료 무결성

UDP는 배달도 순서도 보장하지 않지만, 체크섬으로 자료 무결성은 지켜요.

수신하면 체크섬을 다시 계산해요.

  • 값이 맞으면 데이터그램을 받아들여요.

  • 아니면 바로 버려요.

그래서 UDP는 망가진 자료를 감지하지만, 되찾으려고 절대 시도하지 않아요.

UDP가 왜 이렇게 빠른가요?

UDP 헤더는 8바이트뿐이고, TCP는 최소 20바이트예요 (타임스탬프, SACK, 윈도 스케일링 같은 옵션 제외).

유지되는 연결이 없으니 운영체제가 각 교환 상태를 따라갈 필요가 없어서 메모리 소비와 처리 비용도 줄어요.

애플리케이션은 혹시 모를 재전송을 기다리지 않고 도착하자마자 거의 바로 자료를 받아요.

자료를 잃는 것이 나을 때

기본 생각은 단순해요.

오래된 정보는 사라진 정보보다 가치가 떨어질 수 있어요.

VoIP 통화를 가져와요.

각 패킷은 약 20ms 음성을 나르요.

패킷 하나가 사라지면 다시 보내는 데 이 20ms보다 오래 걸리는 경우가 많아요.

겨우 도착했을 때는 대화가 이미 앞으로 나아가 있어요.

대부분 애플리케이션은 재전송을 기다리기보다 손실 가리기(보간, 무음, 오류 정정)를 택해요.

같은 논리가 적용돼요.

  • 실시간 멀티플레이어 게임;

  • 비디오 스트리밍;

  • 텔레메트리 흐름;

  • IoT 센서;

  • GPS 위치 자료.

최근 값은 완벽히 믿을 만한 오래된 값보다 거의 항상 유용해요.

수준 2: 암호화, TLS

TLS(Transport Layer Security, SSL의 후계자)는 TCP를 대신하지 않고 위에 얹어요. 구체적으로 TLS는 정상 TCP 연결을 맺은 뒤 안에 암호화된 세션을 협상해요. 인증서 교환, 암호화 알고리즘 합의, 세션 키 유도. 그 뒤에 지나가는 모든 것은 암호화되고 인증돼요.

흔히 섞이는 세 가지 서로 다른 보장:

  • 기밀성: 두 당사자 말고는 누구도 내용을 읽을 수 없어요.

  • 무결성: 전송 중 자료 변경은 모두 감지돼요.

  • 인증: 하지만 고전 TLS에서는 단방향이에요. 클라이언트는 서버가 말하는 그 사람인지 확인해요 (신뢰할 수 있는 기관이 서명한 인증서 경유). 서버는 클라이언트 신원에 대해 아무것도 확인하지 않아요. 사이트에 들어갈 때 HTTPS 모델이 정확히 그거예요. 브라우저는 사이트를 인증하고, 사이트는 여러분을 인증하지 않아요 (사용자 인증은 별도 구조, 세션 쿠키와 토큰으로 지나가요).

TLS 1.3(현재 권장 버전)은 흔한 경우 핸드셰이크를 한 번 왕복으로 줄였어요. TLS 1.2의 두 번과 달라서 연결 지연을 눈에 띄게 줄여요.

수준 2bis: mTLS. 인증이 상호가 돼요

mTLS(mTLS)는 제약 하나가 더 붙은 TLS예요. 서버도 클라이언트 인증서를 요구하고 확인해요. 양쪽이 공통으로 신뢰하는 기관이 서명한 인증서로 신원을 증명해요.

분산 아키텍처에서 서비스 대 서비스 통신의 자연스러운 구조예요. 고전 HTTPS가 브라우저와 공개 서버 대화에 충분하다면, mTLS는 다른 질문에 답해요. 내부 서비스는 어떻게 상대가 허용된 다른 내부 서비스인지, 네트워크에 들어온 공격자가 아닌지 알 수 있을까요?

Client                                          Serveur
  │──── ClientHello ─────────────────────────────▶│
  │◀─── ServerHello + certificat serveur ──────────│
  │──── vérifie le certificat serveur ─────────────│
  │──── envoie SON PROPRE certificat client ──────▶│
  │◀─── vérifie le certificat client ───────────────│
  │──── clés de session dérivées, canal chiffré ──▶│

mTLS의 대가는 운영이에요. 내부 인증 기관(CA)과 각 서비스에 인증서를 나눠주는 구조, 교체와 폐기 전략이 필요해요. 서비스가 적은 단일 기기 환경에서는 이득보다 복잡함이 클 때가 있어요. 서비스 사이 트래픽이 완전히 통제하지 못하는 네트워크를 지날 때(여러 호스트, 멀티테넌트 클라우드)부터, 또는 네트워크 "안"에 있다는 이유만으로 어떤 서비스도 암묵적으로 믿지 않는 제로 트러스트 정책을 원할 때부터 mTLS가 필요해져요.

수준 3: TCP와 TLS 위의 애플리케이션 프로토콜

전송과 암호화가 자리 잡으면 남은 것은 교환을 어떻게 구조화할지 정하는 거예요. 애플리케이션 프로토콜의 역할이에요.

HTTP와 HTTPS

HTTP는 요청-응답 프로토콜이에요. 클라이언트가 연결을 열고 (킵얼라이브로 재사용해요), 요청을 보내고, 응답을 기다려요. 연결은 그 뒤에 닫히거나 재사용될 수 있어요. HTTPS는 TLS 위의 HTTP일 뿐이에요. S는 프로토콜 의미를 바꾸지 않고, 전송이 암호화된다는 것만 바꿔요.

요청-응답 모델에는 구조적 한계가 있어요. 서버는 먼저 말할 수 없어요. 클라이언트가 묻는 것에만 답할 수 있어요. 잦은 폴링("새 것 있어요?"를 1초마다 확인)에 동작하지만 자원을 낭비해요. 매 요청이 프로토콜 오버헤드를 새로 만들고, 대부분은 알릴 새 것이 없어요.

WebSocket (WS와 WSS)

WebSocket은 바로 이 한계에 답해요. 연결은 고전 HTTP 요청으로 시작해요 (Upgrade: websocket 헤더와 함께). 하지만 핸드셰이크가 받아들여지면 밑바탕 TCP 연결은 더 이상 HTTP 요청-응답 채널이 아니에요. 클라이언트와 서버가 언제든 메시지를 보낼 수 있는 전이중 양방향 채널이 돼요. 매 교환마다 요청-응답 사이클을 다시 내지 않아도요.

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

WSS는 TLS 위의 WebSocket일 뿐이고, HTTPS가 TLS 위의 HTTP인 것과 똑같아요. 서버 푸시가 실시간으로 필요한 모든 것의 선택 프로토콜이에요. 채팅, 알림, 트레이딩 흐름, 게임 이벤트. 날것 TCP 위에 바이너리 프로토콜을 직접 다루고 싶지 않을 때요.

gRPC

마이크로서비스 세상 밖에서는 덜 알려졌지만 서비스 대 서비스 통신의 중심이에요. gRPC는 HTTP/2에 기대고(그래서 TCP와 선택적 TLS), 메시지를 Protocol Buffers(이진, 타입 있음, 간결. 대부분 REST API의 텍스트 JSON과 달라요)로 직렬화하고, HTTP/2 멀티플렉싱 덕분에 양방향 스트리밍을 네이티브로 허용해요 (하나의 TCP 연결에 여러 논리 흐름, 여러 순차 HTTP/1.1 요청이 가질 head-of-line 블로킹 없이).

QUIC와 HTTP3

QUIC는 전송 수준에서 TCP가 아니라 UDP에서 다시 시작하면서 판을 바꿔요. TCP가 네이티브로 주던 믿을 만함 보장을 위에 다시 구현해요. 하지만 전체가 아니라 흐름별로요. 그래서 전송 수준 head-of-line 블로킹이 사라져요 (한 흐름의 손실 패킷이 같은 연결의 다른 흐름을 더 이상 막지 않아요). TLS 1.3은 위에 얹지 않고 QUIC 안에 직접 통합돼서 핸드셰이크 지연을 더 줄여요. HTTP/3은 QUIC 위의 HTTP예요.

전체 보기: 각 프로토콜의 자리

층 프로토콜 역할
전송 TCP, UDP 바이트 나르기, 믿을 만하거나 아니거나
전송 (새 세대) QUIC UDP + 흐름별 믿을 만함 + 통합 TLS
보안 TLS, mTLS 암호화, 무결성, 인증 (단방향 또는 상호)
애플리케이션 HTTP/HTTPS, WS/WSS, gRPC 교환 구조화 (요청-응답, 양방향, 타입 RPC)

생각을 굳히는 구체 예시예요. 웹 대시보드와 내부 서비스가 있는 마이크로서비스 아키텍처는 HTTPS(대시보드와 공개 API 사이, 브라우저 쪽 단방향 인증이면 충분), mTLS(내부에서 서비스와 서비스 사이, 상호 인증 필요), WSS(대시보드로 미는 실시간 알림) 조합이 합리적일 수 있어요. 서로 다른 애플리케이션 프로토콜 셋이지만 모두 같은 TCP와 TLS 토대 위에 지어져요.

실제로 고르기

보통 세 가지 질문이면 정해져요.

  1. 믿을 만함과 순서가 필요한가요, 아니면 보장된 배달보다 자료 신선함이 우선인가요? → 예라면 TCP, 아니면 UDP (또는 다른 절충으로 둘 다 원하면 QUIC).

  2. 서버가 메시지를 먼저 보낼 수 있어야 하나요, 아니면 클라이언트가 항상 먼저 요청하나요? → 서버가 밀어야 하면 WebSocket과 gRPC 스트리밍, 아니면 고전 HTTP.

  3. 양쪽이 서로 신원을 증명해야 하나요, 아니면 한쪽만 확인되면 되나요? → 제로 트러스트 환경의 서비스 대 서비스에는 mTLS, 고전 공개 클라이언트에는 단순 TLS.

추가되는 층마다 운영 복잡함이 커져요. 날것 TCP에는 관리할 인프라가 없고, TLS에는 인증서가 필요하고, mTLS에는 CA와 교체 전략이 필요하고, gRPC에는 공유 Protobuf 스키마 정의가 필요해요. 밑 층이 구체적 한계를 보일 때만 복잡함을 올리는 것이 좋은 반사 행동이지, 미리 올리는 것이 아니에요.

Makineler birbiriyle nasıl konuşur: TCP'den mTLS'e bir tur

TCP, UDP, TLS, mTLS, HTTP ve WebSocket neden rakip alternatifler değil, üst üste yığılmış katmanlardır; ham aktarımdan karşılıklı kimlik doğrulamaya makineden makineye iletişimin hiyerarşik turu.

Sorun: çok fazla kısaltma, yeterince hiyerarşi yok

TCP, UDP, TLS, mTLS, WebSocket, HTTP, HTTPS, gRPC, QUIC; bunlardan bahseden kaynakların çoğu bunları "kullanım durumuna göre seçilecek" birbirinin yerine geçebilir düz bir seçenek listesi olarak sunar. Gerçekte aynı düzlemde değillerdir: bazıları aktarım protokolleridir, bazıları aktarımın etrafına sarılan güvenlik katmanlarıdır, bazıları ise ilk ikisine dayanan uygulama protokolleridir. Hiyerarşiyi anlamak, neden TCP ile TLS arasında asla "seçim" yapmadığımızı anlamaktır: TCPyi seçeriz, sonra üzerine TLS koyup koymayacağımıza karar veririz.

Bu makale bu hiyerarşiyi katman katman, ham aktarımdan karşılıklı kimlik doğrulamaya yeniden inşa eder; her seviye için neyi garanti ettiği, neyi garanti etmediği ve ne zaman onunla yetinileceğiyle.

Seviye 1: aktarım (TCPye karşı UDP)

Her şey burada başlar. TCP ve UDP, OSI modelinin Aktarım (Katman 4) katmanının iki ana protokolüdür. Rolleri aynıdır: farklı makinelerde çalışan iki uygulama arasında bir veri akışı taşımak. Oysa bunu başarma biçimleri kökten farklıdır.

IPnin (Internet Protocol), ağ katmanında (Katman 3) bulunan, paketleri yalnızca bir hosttan diğerine ilettiğini anlamak önemlidir. Ne varmalarını, ne sıralarını, ne de benzersizliklerini garanti eder. Yönlendiriciler her paket için basitçe bağımsız yönlendirme kararları alır.

TCPnin telafi etmeye geldiği şey tam olarak bu garanti yokluğudur, oysa UDP bilinçli olarak aşırı hafif kalmak için hiçbir şey eklememeyi seçer.

TCP: önce güvenilirlik

TCP (Transmission Control Protocol) bağlantı yönelimli (connection-oriented) bir protokoldür. Tek bir veri baytı değiş tokuş etmeden önce iki makine mantıksal bir bağlantı kurmalıdır.

Bu bağlantı ünlü Three-Way Handshake sayesinde oluşturulur:


Client                           Serveur
SYN ---------------------------->
        <--------------------- SYN + ACK
ACK ----------------------------> 
Connexion établie

Her adımın kesin bir amacı vardır:

  • SYN: istemci bir bağlantı açmak istediğini duyurur ve ilk sıra numarasını verir (Initial Sequence Number - ISN).

  • SYN-ACK: sunucu bağlantıyı kabul eder, SYNi onaylar ve sırayla kendi sıra numarasını verir.

  • ACK: istemci sunucunun bilgilerinin alındığını onaylar.

Bu andan itibaren iki makine bağlantının durumunu bilir ve veri değiş tokuş etmeye başlayabilir.

Sıra numaraları

TCP verileri bir paket dizisi olarak değil, sürekli bir bayt akışı (byte stream) olarak görür.

Gönderilen her baytın bir sıra numarası vardır.

Örnek:

Message :

Bonjour

B = octet 0
o = octet 1
n = octet 2
...

Aktarım sırasında 1000 ila 1499 baytlarını içeren bir parça kaybolursa alıcı tam olarak neyin eksik olduğunu tespit edebilir.

Gönderici yalnızca o kısmı yeniden iletir.

Bu ayrıntı düzeyi TCPnin sağlamlığının nedenlerinden biridir.

Alındı onayları (ACK)

Verileri aldıktan sonra hedef bir ACK (Acknowledgment) gönderir.

Genelde hayal edilenin tersine bir ACK şu anlama gelmez:

"Bu paketi aldım"

Daha çok şu anlama gelir:

"X numarasına kadar tüm baytları aldım."

Örneğin:

Client envoie :

0 → 999

Serveur répond :

ACK = 1000

Bu şu demektir:

"1000 baytından önceki her şey sağ salim vardı."

Bu mekanizma birkaç parçayı aynı anda onaylamaya izin verir (cumulative acknowledgments), böylece kontrol paketi sayısını azaltır.

Yeniden iletimler

Bir ACK hiç gelmezse TCP parçanın kaybolduğunu varsayar.

Onu otomatik olarak yeniden iletir.

Yeniden iletim gecikmesi (Retransmission Timeout: RTO) sabit değildir.

TCP alınan ACKler sayesinde gidiş dönüş süresini (RTT) sürekli ölçer ve gereksiz yeniden iletimlerden kaçınmak için RTOyu dinamik hesaplar.

Modern uygulamalar Fast Retransmit gibi mekanizmalar da kullanır: bir gönderici birkaç yinelenen ACK aldığında (genelde üç) arada bir parçanın kaybolduğu sonucunu çıkarır ve zamanlayıcının dolmasını beklemeden hemen yeniden gönderir.

Paketlerin yeniden sıralanması

İnternet iki paketin aynı yolu izleyeceğini kesinlikle garanti etmez.

Örnek:

Paquet 1
Paris
  ↓
Londres
  ↓
New York

Paquet 2
Paris
  ↓
Francfort
  ↓
Chicago
  ↓
New York

İkinci paket birinciden önce varabilir.

TCP sıra dışı alınan parçaları geçici olarak bir tamponda (reassembly buffer) saklar, sonra uygulamaya teslim etmeden önce yeniden birleştirir.

Uygulama için her şey mükemmel sırayla geliyormuş gibi görünür.

Akış kontrolü

Bir bağlantı yalnızca ağa bağlı değildir.

Alıcının da sınırlı bir bellek kapasitesi vardır.

Verileri işleyebildiğinden hızlı alırsa tamponları dolar.

TCP bu sorunu kayan bir pencere (Sliding Window) sayesinde çözer.

Alıcı her ACK içinde şunu belirtir:

Window = 32768 octets

Bu şu demektir:

"Bana 32 KB daha gönderebilirsin."

Bu pencere sıfıra düşerse:

Window = 0

Gönderici, alıcı yeni bir uygun pencere duyurana kadar iletimleri geçici askıya alır.

Bu mekanizma akış kontrolünü (Flow Control) oluşturur ve hızlı bir hostun daha yavaş bir hostu boğmasını engeller.

Tıkanıklık kontrolü

Alıcı verileri soğurabilse bile ağın kendisi doygun hale gelebilir.

Yönlendiricilerin sınırlı kuyrukları (queues) vardır.

Taştıklarında paketler silinir.

TCP kayıpları tıkanıklık işareti olarak yorumlar ve bir tıkanıklık penceresi (Congestion Window: cwnd) sayesinde hızını otomatik uyarlar.

Modern algoritmalar (işletim sistemine göre Reno, CUBIC ya da BBR gibi) maksimum hız ile ağ kararlılığı arasında denge bulmak için bu pencereyi ayarlar.

TCPnin ilk sürümleri başlıca iki mekanizma kullanıyordu:

  • Slow Start: tıkanıklık tespit edilene kadar hızın üstel artışı.

  • Congestion Avoidance: sonra daha temkinli, genelde doğrusal büyüme.

Bu sürekli uyarlama, ağ kalite değişimlerine rağmen TCPnin performanslı kalmasının nedenlerinden biridir.

Bağlantıyı kapatma

UDPnin tersine bir TCP bağlantısının temiz bir kapanışı da vardır.

Her uç FIN bayrağıyla akışını bağımsız kapatır.

Tam bir kapanış genelde dört değiş tokuş gerektirir:

FIN
ACK
FIN
ACK

Bu prosedür, bağlantı yok edilmeden önce transit tüm verilerin gerçekten teslim edildiğini garanti eder.

UDP: maksimum sadelik

UDP (User Datagram Protocol) ters felsefeyi benimser.

Bağlantısızdır (connectionless).

Şunlar yoktur:

  • handshake yok;

  • sıra numarası yok;

  • alındı onayı yok;

  • yeniden iletim yok;

  • akış kontrolü yok;

  • tıkanıklık kontrolü yok.

Her mesaj basitçe bağımsız bir datagramda kapsüllenir, ağa iletilir, sonra gönderici tarafından unutulur.

Application → Datagramme UDP → IP → Internet

Protokol iki gönderi arasında durum tutmaz.

Her datagram öncekilerden tamamen bağımsızdır.

Veri bütünlüğü

UDP ne teslimi ne sırayı garanti etse de yine de bir checksum sayesinde veri bütünlüğünü korur.

Alımda checksum yeniden hesaplanır.

  • Değerler uyuşursa datagram kabul edilir.

  • Yoksa hemen reddedilir.

Yani UDP bozuk verileri tespit eder ama onları kurtarmaya asla çalışmaz.

UDP neden bu kadar hızlı?

UDP başlığı yalnızca 8 bayt içerir, seçenekler sayılmadan minimum 20 bayt olan TCPye karşı (timestamps, SACK ya da Window Scaling gibi seçenekler hariç).

Bakımı yapılan bağlantı olmadığı için işletim sistemi her değiş tokuşun durumunu izlemek zorunda değildir, bu da bellek tüketimini ve işleme maliyetini azaltır.

Uygulama verileri varır varmaz, olası yeniden iletimleri beklemeden alır.

Veri kaybetmenin tercih edilir olduğu durum

Temel fikir basittir:

Eski bir bilgi kayıp bir bilgiden daha az değerli olabilir.

Bir VoIP konuşmasını alalım.

Her paket yaklaşık 20 ms ses taşır.

Bir paket kaybolursa yeniden iletmek genelde bu 20 msden uzun sürer.

Sonunda vardığında konuşma çoktan ilerlemiştir.

Çoğu uygulama o zaman kaybı maskelemeyi (interpolasyon, sessizlik, hata düzeltme) yeniden iletimi beklemeye tercih eder.

Aynı mantık şunlara uygulanır:

  • gerçek zamanlı çok oyunculu oyunlar;

  • video akışı;

  • telemetri akışları;

  • IoT sensörleri;

  • GPS konum verileri.

Yeni bir değer neredeyse her zaman mükemmel güvenilir eski bir değerden daha faydalıdır.

Seviye 2: şifreleme, TLS

TLS (Transport Layer Security, SSLin halefi) TCPnin yerini almaz, üzerine eklenir. Somut olarak TLS normal bir TCP bağlantısı kurar, sonra içinde şifreli bir oturum müzakere eder: sertifika değişimi, şifreleme algoritmasında anlaşma, oturum anahtarlarının türetilmesi. Sonra geçen her şey şifrelenir ve kimliği doğrulanır.

Genelde karıştırılan üç ayrı garanti:

  • Gizlilik: iki taraftan başka kimse içeriği okuyamaz.

  • Bütünlük: transitte verilerin her değişimi tespit edilir.

  • Kimlik doğrulama: ama klasik TLS de tek yönlüdür: istemci sunucunun iddia ettiği kişi olduğunu doğrular (güvenilir bir otoritece imzalı sertifikası üzerinden) ama sunucu istemcinin kimliği hakkında hiçbir şey doğrulamaz. Bir siteyi ziyaret ettiğinde HTTPS modeli tam olarak budur: tarayıcı siteyi doğrular, site seni doğrulamaz (kullanıcı doğrulama ayrı bir mekanizmadan geçer, oturum çerezi, jeton).

TLS 1.3 (önerilen güncel sürüm) handshakei yaygın durumda tek gidiş dönüşe indirdi, TLS 1.2deki ikiye karşı, bu da bağlantı gecikmesini belirgin azaltır.

Seviye 2bis: mTLS, kimlik doğrulama karşılıklı olur

mTLS (mutual TLS), ek bir kısıtlı TLS tir: sunucu istemciden de bir sertifika ister ve onu doğrular. İki taraf da ortak güvenilir bir otoritece imzalı bir sertifika üzerinden kimliğini kanıtlar.

Dağıtık bir mimaride servisten servise iletişim için doğal mekanizmadır: klasik HTTPS bir tarayıcının herkese açık bir sunucuyla konuşması için yeterliyken mTLS farklı bir soruyu yanıtlar; bir iç servis, yetkili başka bir iç servisle konuştuğunu, ağa düşmüş bir saldırganla değil, nereden bilir?

Client                                          Serveur
  │──── ClientHello ─────────────────────────────▶│
  │◀─── ServerHello + certificat serveur ──────────│
  │──── vérifie le certificat serveur ─────────────│
  │──── envoie SON PROPRE certificat client ──────▶│
  │◀─── vérifie le certificat client ───────────────│
  │──── clés de session dérivées, canal chiffré ──▶│

mTLSin karşılığı operasyoneldir: bir iç sertifika otoritesi (CA), her servise sertifika dağıtım mekanizması ve döndürme/iptal stratejisi gerekir. Az servisli tek makineli bir ortamda bu bazen faydadan çok karmaşıklıktır: mTLS, servisler arası trafik tam kontrol etmediğimiz bir ağdan geçtiği andan (birden çok host, çok kiracılı bulut) ya da zero trust türü bir politika istendiği andan itibaren gerekli olur; ağın "içinde" olması sırfıyla hiçbir servis örtük güvenilir sayılmaz.

Seviye 3: TCP+TLS üstündeki uygulama protokolleri

Aktarım ve şifreleme yerinde olduğunda değiş tokuşların nasıl yapılandırılacağını tanımlamak kalır. Uygulama protokollerinin rolü budur.

HTTP / HTTPS

HTTP bir istek yanıt protokolüdür: istemci bir bağlantı açar (ya da keep-alive ile yeniden kullanır), bir istek gönderir, bir yanıt bekler, bağlantı sonra kapanabilir ya da yeniden kullanılabilir. HTTPS basitçe TLS üzerinde HTTPdir: S protokolün semantiğini hiç değiştirmez, yalnızca aktarımın şifreli olduğu gerçeğini değiştirir.

İstek yanıt modelinin yapısal bir limiti vardır: sunucu asla önce konuşamaz. Yalnızca istemcinin istediğine yanıt verebilir. Sık yoklama için (her saniye "yeni bir şey var mı?" diye kontrol etmek) çalışır ama kaynak israf eder: çoğu zaman duyuracak yeni bir şey yokken her istek protokol yükünü yeniden yaratır.

WebSocket (WS / WSS)

WebSocket tam olarak bu limite yanıt verir. Bağlantı klasik bir HTTP isteği olarak başlar (Upgrade: websocket başlığıyla) ama el sıkışma kabul edildikten sonra alttaki TCP bağlantısı artık bir HTTP istek yanıt kanalı değildir: istemci ve sunucunun her değiş tokuşta bir istek yanıt döngüsünü yeniden yayımlamadan istediği zaman mesaj gönderebildiği çift yönlü tam çift yönlü bir kanala dönüşür.

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

WSS basitçe TLS üzerinde WebSocket tir, tıpkı HTTPSin TLS üzerinde HTTP olması gibi. Çıplak TCP üstünde kendi ikili protokolünü yönetmek istemeden gerçek zamanlı sunucu itmesi gerektiren her şey için seçim protokolüdür: sohbet, bildirimler, alım satım akışları, oyun olayları.

gRPC

Mikroservis dünyası dışında az bilinir ama servisten servise iletişimde merkezidir: gRPC HTTP/2ye dayanır (yani TCP + opsiyonel TLS), mesajları Protocol Buffers ile serileştirir (çoğu REST API sinin metin JSONunun tersine ikili, tipli, kompakt) ve HTTP/2nin çoklaması sayesinde doğal olarak çift yönlü akışa izin verir (head-of-line blocking olacak birkaç sıralı HTTP/1.1 isteğinin tersine tek bir TCP bağlantısında birkaç mantıksal akış).

QUIC / HTTP3

QUIC, aktarım seviyesinde TCP yerine UDPden başlayarak oyunu değiştirir, üstüne TCPnin doğal sunduğu güvenilirlik garantilerini yeniden uygular: ama küresel yerine akış akış, bu da aktarım seviyesinde head-of-line blockingi ortadan kaldırır (bir akışta kaybolan bir paket aynı bağlantının diğer akışlarını artık bloklamaz). TLS 1.3, üzerine eklenmek yerine doğrudan QUIC içine gömülüdür, bu da handshake gecikmesini daha da azaltır. HTTP/3, QUIC üzerinde HTTPdir.

Genel bakış: her protokol nerede durur

Katman Protokoller Rol Aktarım TCP, UDP Baytları gezdirmek, güvenilir ya da değil Aktarım (yeni nesil) QUIC UDP + akış başı güvenilirlik + gömülü TLS Güvenlik TLS, mTLS Şifreleme, bütünlük, kimlik doğrulama (tek ya da karşılıklı) Uygulama HTTP/HTTPS, WS/WSS, gRPC Değiş tokuşları yapılandırmak (istek yanıt, çift yönlü, tipli RPC)

Somut bir örnek fikirleri sabitlemek için: web panolu ve iç servisli bir mikroservis mimarisi makul şekilde HTTPS (pano ↔ herkese açık API, tarayıcı tarafında tek yönlü doğrulama yeterli), mTLS (dâhili servisten servise, karşılıklı doğrulama gerekli) ve WSS (panoya itilen gerçek zamanlı bildirimler) birleştirebilir: üç farklı uygulama protokolü, hepsi aynı TCP + TLS tabanı üstüne inşa edilmiş.

Pratikte nasıl seçmeli

Genelde karar vermek için üç soru yeter:

  1. Güvenilirliğe ve sıraya mı ihtiyacım var, yoksa verinin tazeliği garantili tesliminden önce mi gelir? → Evetse TCP, hayırsa UDP (ya da farklı bir uzlaşmayla ikisini birden almak için QUIC).

  2. Sunucu mesaj başlatabilmeli mi, yoksa istemci hep ilk isteği mi yapar? → Sunucu itmeliyse WebSocket/gRPC akışı, yoksa klasik HTTP.

  3. İki taraf da birbirine kimliğini kanıtlamalı mı, yoksa yalnızca birinin doğrulanması mı gerekir? → zero-trust ortamında servisten servise için mTLS, klasik herkese açık istemci için basit TLS.

Eklenen her katmanda operasyonel karmaşıklık artar, çıplak TCPnin yönetilecek altyapısı yoktur, TLS sertifika ister, mTLS bir CA ve döndürme stratejisi ister, gRPC paylaşılan bir Protobuf şema tanımı ister. Doğru refleks, karmaşıklığa ancak alttaki katman somut bir limit gösterdiğinde çıkmaktır, önceden değil.

Come si parlano le macchine: panoramica da TCP a mTLS

Perché TCP, UDP, TLS, mTLS, HTTP e WebSocket non sono alternative concorrenti ma strati impilati; una panoramica gerarchica della comunicazione macchina-macchina, dal trasporto grezzo all'autenticazione mutua.

Il problema: troppe sigle, poca gerarchia

TCP, UDP, TLS, mTLS, WebSocket, HTTP, HTTPS, gRPC, QUIC; quasi tutte le risorse che ne parlano le presentano come una lista piatta di opzioni intercambiabili, "da scegliere secondo il caso d'uso". In realtà non sono sullo stesso piano: alcuni sono protocolli di trasporto, altri strati di sicurezza che si avvolgono intorno al trasporto, altri ancora protocolli applicativi che si appoggiano sui primi due. Capire la gerarchia, è capire perché non "scegli" mai tra TCP e TLS: scegli TCP, poi decidi se mettere TLS sopra.

Questo articolo ricostruisce questa gerarchia strato per strato, dal trasporto grezzo fino all'autenticazione mutua, con per ogni livello: cosa garantisce, cosa non garantisce, e quando accontentarsene.

Livello 1: il trasporto (TCP contro UDP)

Tutto inizia qui. TCP e UDP sono i due principali protocolli dello strato Trasporto (Layer 4) del modello OSI. Il loro ruolo è identico: trasportare un flusso di dati tra due applicazioni eseguite su macchine diverse. Eppure, il loro modo di riuscirci è radicalmente diverso.

È importante capire che IP (Internet Protocol), situato allo strato rete (Layer 3), fa solo instradare pacchetti da un host a un altro. Non garantisce né il loro arrivo, né il loro ordine, né la loro unicità. I router prendono semplicemente decisioni di routing indipendenti per ogni pacchetto.

È proprio questa assenza di garanzie che TCP viene a compensare, mentre UDP sceglie deliberatamente di non aggiungere niente per restare estremamente leggero.

TCP: l'affidabilità prima di tutto

TCP (Transmission Control Protocol) è un protocollo orientato alla connessione (connection-oriented). Prima di scambiare il minimo byte di dati, le due macchine devono stabilire una connessione logica.

Questa connessione è creata grazie al famoso Three-Way Handshake:


Client                           Server
SYN ---------------------------->
        <--------------------- SYN + ACK
ACK ---------------------------->
Connessione stabilita

Ogni passo ha un obiettivo preciso:

  • SYN: il client annuncia che vuole aprire una connessione e fornisce un primo numero di sequenza (Initial Sequence Number - ISN).

  • SYN-ACK: il server accetta la connessione, accusa ricevuta del SYN e fornisce a sua volta il suo numero di sequenza.

  • ACK: il client conferma la ricevuta delle informazioni del server.

Da questo momento, le due macchine conoscono lo stato della connessione e possono iniziare a scambiare dati.

I numeri di sequenza

TCP non vede i dati come una successione di pacchetti, ma come un flusso continuo di byte (byte stream).

Ogni byte inviato ha un numero di sequenza.

Esempio:

Messaggio:

Buongiorno

B = byte 0
u = byte 1
o = byte 2
...

Se un segmento contenente i byte da 1000 a 1499 è perso durante il trasporto, il ricevente può rilevare esattamente cosa manca.

Il mittente ritrasmette solo quella porzione.

Questa granularità è una delle ragioni della robustezza di TCP.

Le ricevute (ACK)

Dopo la ricevuta dei dati, il destinatario invia un ACK (Acknowledgment).

Contrariamente a ciò che spesso si immagina, un ACK non significa:

"Ho ricevuto questo pacchetto"

Significa piuttosto:

"Ho ricevuto tutti i byte fino al numero X."

Per esempio:

Client invia:

0 → 999

Server risponde:

ACK = 1000

Questo significa:

"Tutto ciò che precede il byte 1000 è arrivato bene."

Questo meccanismo permette di accusare ricevuta di più segmenti insieme (cumulative acknowledgments), riducendo così il numero di pacchetti di controllo.

Le ritrasmissioni

Se un ACK non arriva mai, TCP suppone che il segmento sia perso.

Lo ritrasmette automaticamente.

Il ritardo di ritrasmissione (Retransmission Timeout – RTO) non è fisso.

TCP misura in permanenza il tempo di andata-ritorno (RTT) grazie agli ACK ricevuti e calcola dinamicamente l'RTO per evitare ritrasmissioni inutili.

Le implementazioni moderne usano anche meccanismi come Fast Retransmit: quando un mittente riceve più ACK duplicati (generalmente tre), deduce che un segmento intermedio è stato perso e lo rinvia subito, senza aspettare la scadenza del timer.

Riordino dei pacchetti

Internet non garantisce assolutamente che due pacchetti seguano lo stesso percorso.

Esempio:

Pacchetto 1
Parigi
  ↓
Londra
  ↓
New York

Pacchetto 2
Parigi
  ↓
Francoforte
  ↓
Chicago
  ↓
New York

Il secondo pacchetto può arrivare prima del primo.

TCP salva allora temporaneamente i segmenti ricevuti fuori ordine in un buffer (reassembly buffer), poi li riassembla prima di consegnarli all'applicazione.

Per l'applicazione, tutto sembra arrivare perfettamente in ordine.

Controllo di flusso

Una connessione non dipende solo dalla rete.

Il ricevente ha anche una capacità di memoria limitata.

Se riceve più in fretta di quanto riesca a elaborare i dati, i suoi buffer finiscono per saturarsi.

TCP risolve questo problema grazie a una finestra scorrevole (Sliding Window).

Il ricevente indica in ogni ACK:

Window = 32768 byte

Questo significa:

"Puoi inviarmi fino a 32 KB in più."

Se questa finestra cade a zero:

Window = 0

Il mittente sospende temporaneamente le trasmissioni finché il ricevente annuncia una nuova finestra disponibile.

Questo meccanismo costituisce il controllo di flusso (Flow Control) e impedisce che un host rapido inondi un host più lento.

Controllo di congestione

Anche se il ricevente è capace di assorbire i dati, la rete stessa può saturarsi.

I router hanno code (queues) limitate.

Quando traboccano, i pacchetti sono scartati.

TCP interpreta le perdite come un segno di congestione e adatta automaticamente la sua portata grazie a una finestra di congestione (Congestion Window – cwnd).

Gli algoritmi moderni (come Reno, CUBIC o BBR, secondo i sistemi operativi) aggiustano questa finestra per trovare un equilibrio tra portata massima e stabilità della rete.

Le prime versioni di TCP usavano principalmente due meccanismi:

  • Slow Start: aumento esponenziale della portata fino a rilevare una congestione.

  • Congestion Avoidance: crescita poi più prudente, generalmente lineare.

Questa adattamento permanente è una delle ragioni per cui TCP resta performante nonostante le variazioni di qualità della rete.

Chiusura di connessione

A differenza di UDP, una connessione TCP ha anche una chiusura pulita.

Ogni estremità chiude indipendentemente il suo flusso grazie al flag FIN.

Una chiusura completa richiede generalmente quattro scambi:

FIN
ACK
FIN
ACK

Questa procedura garantisce che tutti i dati in transito siano stati ben consegnati prima della distruzione della connessione.

UDP: la semplicità massima

UDP (User Datagram Protocol) adotta la filosofia inversa.

È senza connessione (connectionless).

Non esiste:

  • alcun handshake;

  • alcun numero di sequenza;

  • alcuna ricevuta;

  • alcuna ritrasmissione;

  • alcun controllo di flusso;

  • alcun controllo di congestione.

Ogni messaggio è semplicemente incapsulato in un datagramma indipendente, trasmesso alla rete, poi dimenticato dal mittente.

Applicazione → Datagramma UDP → IP → Internet

Il protocollo non conserva alcuno stato tra due invii.

Ogni datagramma è totalmente indipendente dai precedenti.

L'integrità dei dati

Anche se UDP non garantisce né consegna né ordine, protegge comunque l'integrità dei dati grazie a un checksum.

Alla ricevuta, il checksum è ricalcolato.

  • Se i valori corrispondono, il datagramma è accettato.

  • Altrimenti, è subito scartato.

UDP rileva quindi i dati corrotti, ma non prova mai a recuperarli.

Perché UDP è così rapido?

L'header UDP contiene solo 8 byte, contro un minimo di 20 byte per TCP (senza contare le opzioni come timestamp, SACK o Window Scaling).

Dato che nessuna connessione è mantenuta, il sistema operativo non deve seguire lo stato di ogni scambio, il che riduce anche consumo di memoria e costo di elaborazione.

L'applicazione riceve i dati quasi appena arrivano, senza aspettare eventuali ritrasmissioni.

Quando perdere un dato è preferibile

L'idea fondamentale è semplice:

Un'informazione vecchia può avere meno valore di un'informazione persa.

Prendiamo una conversazione VoIP.

Ogni pacchetto trasporta circa 20 ms di voce.

Se un pacchetto è perso, ritrasmetterlo prenderebbe spesso più tempo di questi 20 ms.

Quando arriverebbe infine, la conversazione sarebbe già andata avanti.

Quasi tutte le applicazioni preferiscono allora mascherare la perdita (interpolazione, silenzio, correzione di errore) invece di aspettare la ritrasmissione.

Lo stesso ragionamento si applica:

  • ai giochi multiplayer in tempo reale;

  • allo streaming video;

  • ai flussi di telemetria;

  • ai sensori IoT;

  • ai dati di posizione GPS.

Un valore recente è quasi sempre più utile di un valore vecchio perfettamente affidabile.

Livello 2: la cifratura, TLS

TLS (Transport Layer Security, successore di SSL) non sostituisce TCP, si aggiunge sopra. In concreto, TLS stabilisce una normale connessione TCP, poi negozia una sessione cifrata dentro: scambio di certificati, accordo su un algoritmo di cifratura, derivazione di chiavi di sessione. Tutto ciò che transita poi è cifrato e autenticato.

Tre garanzie distinte, spesso confuse:

  • Riservatezza: nessun altro oltre le due parti può leggere il contenuto.

  • Integrità: ogni alterazione dei dati in transito è rilevata.

  • Autenticazione: ma nel TLS classico, a senso unico: il client verifica che il server sia bene ciò che pretende di essere (via il suo certificato, firmato da un'autorità di fiducia), ma il server non verifica niente sull'identità del client. È esattamente il modello di HTTPS quando visiti un sito: il browser autentica il sito, il sito non ti autentica (l'autenticazione utente passa da un meccanismo separato, cookie di sessione, token).

TLS 1.3 (la versione attuale raccomandata) ha ridotto l'handshake a un solo andata-ritorno nel caso comune, contro due per TLS 1.2, il che riduce sensibilmente la latenza di connessione.

Livello 2bis: mTLS: l'autenticazione diventa mutua

mTLS (mutual TLS) è TLS con un vincolo in più: il server esige anche un certificato dal client, e lo verifica. Entrambe le parti provano la loro identità via un certificato firmato da un'autorità di fiducia comune.

È il meccanismo naturale per la comunicazione servizio-servizio in un'architettura distribuita: là dove HTTPS classico basta perché un browser parli a un server pubblico, mTLS risponde a una domanda diversa; come fa un servizio interno a sapere che parla bene a un altro servizio interno autorizzato, e non a un attaccante atterrato sulla rete?

Client                                          Server
  │──── ClientHello ─────────────────────────────▶│
  │◀─── ServerHello + certificato server ──────────│
  │──── verifica il certificato server ─────────────│
  │──── invia il SUO certificato client ──────────▶│
  │◀─── verifica il certificato client ───────────────│
  │──── chiavi di sessione derivate, canale cifrato ──▶│

La contropartita di mTLS è operativa: serve un'autorità di certificazione (CA) interna, un meccanismo di distribuzione dei certificati a ogni servizio, e una strategia di rotazione/revoca. In un ambiente mono-macchina con pochi servizi, è a volte più complessità che beneficio: mTLS diventa necessario dal momento in cui il traffico inter-servizi attraversa una rete che non controlliamo interamente (più host, cloud multi-tenant), o appena vogliamo una politica tipo zero trust, dove nessun servizio è implicitamente degno di fiducia solo perché è "dentro" la rete.

Livello 3: i protocolli applicativi sopra TCP+TLS

Una volta messi trasporto e cifratura, resta da definire come strutturare gli scambi. È il ruolo dei protocolli applicativi.

HTTP / HTTPS

HTTP è un protocollo richiesta-risposta: il client apre una connessione (o ne riusa una, col keep-alive), invia una richiesta, aspetta una risposta, la connessione può poi richiudersi o essere riusata. HTTPS, è semplicemente HTTP su TLS: la S non cambia niente alla semantica del protocollo, solo al fatto che il trasporto è cifrato.

Il modello richiesta-risposta ha un limite strutturale: il server non può mai parlare per primo. Può solo rispondere a ciò che il client chiede. Per polling frequente (verificare "c'è qualcosa di nuovo?" ogni secondo), funziona ma spreca risorse: ogni richiesta ricrea overhead protocollare per, quasi sempre, non avere niente di nuovo da annunciare.

WebSocket (WS / WSS)

WebSocket risponde esattamente a questo limite. La connessione inizia come una normale richiesta HTTP (con un header Upgrade: websocket), ma una volta accettato l'handshake, la connessione TCP sottostante non è più un canale richiesta-risposta HTTP: diventa un canale bidirezionale full-duplex dove client e server possono inviare messaggi in qualsiasi momento, senza dover riemettere un ciclo richiesta-risposta a ogni scambio.

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

WSS è semplicemente WebSocket su TLS, esattamente come HTTPS è HTTP su TLS. È il protocollo di scelta per tutto ciò che richiede push server in tempo reale: chat, notifiche, flussi di trading, eventi di gioco: senza voler gestire da sé un protocollo binario sopra TCP nudo.

gRPC

Meno noto fuori dal mondo microservizi ma centrale in comunicazione servizio-servizio: gRPC si appoggia su HTTP/2 (quindi TCP + TLS opzionale), serializza i messaggi in Protocol Buffers (binario, tipizzato, compatto: al contrario del JSON testo di quasi tutte le API REST), e permette nativamente lo streaming bidirezionale grazie al multiplexing di HTTP/2 (più flussi logici su una sola connessione TCP, senza l'head-of-line blocking che avrebbero più richieste HTTP/1.1 sequenziali).

QUIC / HTTP3

QUIC cambia le carte ripartendo da UDP invece di TCP a livello trasporto, reimplementando sopra le garanzie di affidabilità che TCP offriva nativamente: ma flusso per flusso invece che globalmente, il che elimina l'head-of-line blocking a livello trasporto (un pacchetto perso su un flusso non blocca più gli altri flussi della stessa connessione). TLS 1.3 è integrato direttamente in QUIC invece che aggiunto sopra, il che riduce ancora la latenza di handshake. HTTP/3 è HTTP sopra QUIC.

Panoramica: dove sta ogni protocollo

Strato Protocolli Ruolo Trasporto TCP, UDP Far viaggiare byte, affidabile o no Trasporto (nuova generazione) QUIC UDP + affidabilità per flusso + TLS integrato Sicurezza TLS, mTLS Cifratura, integrità, autenticazione (uni o mutua) Applicazione HTTP/HTTPS, WS/WSS, gRPC Strutturare gli scambi (richiesta-risposta, bidirezionale, RPC tipizzato)

Un esempio concreto per fissare le idee: un'architettura microservizi con una dashboard web e servizi interni potrebbe ragionevolmente combinare HTTPS (dashboard ↔ API pubblica, autenticazione unidirezionale sufficiente lato browser), mTLS (servizio ↔ servizio in interno, autenticazione mutua necessaria), e WSS (notifiche tempo reale spinte verso la dashboard): tre protocolli applicativi diversi, tutti costruiti sullo stesso basamento TCP + TLS.

Come scegliere, in pratica

Tre domande bastano generalmente a decidere:

  1. Ho bisogno di affidabilità e ordine, o la freschezza del dato primeggia sulla sua consegna garantita? → TCP se sì, UDP se no (o QUIC per avere entrambi con un compromesso diverso).

  2. Il server deve poter iniziare messaggi, o il client fa sempre la prima richiesta? → WebSocket/gRPC streaming se il server deve spingere, HTTP classico altrimenti.

  3. Entrambe le parti devono provarsi a vicenda la loro identità, o solo una delle due deve essere verificata? → mTLS per servizio-servizio in ambiente zero-trust, TLS semplice per client pubblico classico.

La complessità operativa aumenta a ogni strato aggiunto, TCP nudo non ha alcuna infrastruttura da gestire, TLS chiede certificati, mTLS chiede una CA e una strategia di rotazione, gRPC chiede una definizione di schema Protobuf condivisa. Il buon riflesso è salire in complessità solo quando lo strato sotto mostra un limite concreto, non per anticipazione.

Wie Maschinen miteinander reden: von TCP bis mTLS im Überblick

Warum TCP, UDP, TLS, mTLS, HTTP und WebSocket keine konkurrierenden Alternativen sind, sondern gestapelte Schichten; ein hierarchischer Überblick über Maschine-zu-Maschine-Kommunikation, vom rohen Transport bis zur gegenseitigen Authentifizierung.

Das Problem: zu viele Siglen, zu wenig Hierarchie

TCP, UDP, TLS, mTLS, WebSocket, HTTP, HTTPS, gRPC, QUIC; die meisten Ressourcen, die darüber reden, präsentieren sie als flache Liste austauschbarer Optionen, "je nach Use Case zu wählen". In Wirklichkeit liegen sie nicht auf derselben Ebene: Manche sind Transportprotokolle, andere Sicherheitsschichten, die sich um den Transport wickeln, wieder andere Anwendungsprotokolle, die auf den ersten beiden aufbauen. Die Hierarchie zu verstehen heißt zu verstehen, warum man nie zwischen TCP und TLS "wählt": Man wählt TCP, dann entscheidet man, ob man TLS darüberlegt.

Dieser Artikel baut diese Hierarchie Schicht für Schicht wieder auf, vom rohen Transport bis zur gegenseitigen Authentifizierung, mit für jede Ebene: was sie garantiert, was sie nicht garantiert und wann man sich damit begnügen kann.

Ebene 1: der Transport (TCP gegen UDP)

Alles beginnt hier. TCP und UDP sind die zwei Hauptprotokolle der Transport-Schicht (Layer 4) des OSI-Modells. Ihre Rolle ist identisch: Einen Datenstrom zwischen zwei Anwendungen transportieren, die auf verschiedenen Maschinen laufen. Doch ihre Art, das zu erreichen, ist radikal unterschiedlich.

Wichtig zu verstehen ist, dass IP (Internet Protocol), auf der Netzwerkschicht (Layer 3) angesiedelt, nur Pakete von einem Host zum anderen routet. Es garantiert weder ihre Ankunft noch ihre Reihenfolge, noch nicht einmal ihre Eindeutigkeit. Router treffen einfach unabhängige Routingentscheidungen für jedes Paket.

Genau dieses Fehlen von Garantien kompensiert TCP, während UDP bewusst beschließt, nichts hinzuzufügen, um extrem leicht zu bleiben.

TCP: Zuverlässigkeit zuerst

TCP (Transmission Control Protocol) ist ein verbindungsorientiertes (connection-oriented) Protokoll. Bevor auch nur ein Byte Daten ausgetauscht wird, müssen die zwei Maschinen eine logische Verbindung aufbauen.

Diese Verbindung wird dank des berühmten Three-Way Handshake erstellt:


Client                           Serveur
SYN ---------------------------->
        <--------------------- SYN + ACK
ACK ---------------------------->
Connexion établie

Jeder Schritt hat ein präzises Ziel:

  • SYN: Der Client kündigt an, dass er eine Verbindung öffnen will, und liefert eine erste Sequenznummer (Initial Sequence Number - ISN).

  • SYN-ACK: Der Server akzeptiert die Verbindung, bestätigt den Empfang des SYN und liefert seinerseits seine eigene Sequenznummer.

  • ACK: Der Client bestätigt den Empfang der Serverinformationen.

Ab diesem Moment kennen beide Maschinen den Verbindungszustand und können anfangen, Daten auszutauschen.

Die Sequenznummern

TCP sieht die Daten nicht als Abfolge von Paketen, sondern als kontinuierlichen Bytestrom (byte stream).

Jedes gesendete Byte besitzt eine Sequenznummer.

Beispiel:

Message :

Bonjour

B = octet 0
o = octet 1
n = octet 2
...

Wenn ein Segment mit den Bytes 1000 bis 1499 während des Transports verloren geht, kann der Empfänger exakt erkennen, was fehlt.

Der Sender überträgt nur diesen Teil erneut.

Diese Granularität ist einer der Gründe für TCPs Robustheit.

Die Empfangsbestätigungen (ACK)

Nach Datenempfang schickt der Empfänger ein ACK (Acknowledgment).

Entgegen dem, was man sich oft vorstellt, bedeutet ein ACK nicht:

"Ich habe dieses Paket empfangen"

Es bedeutet eher:

"Ich habe alle Bytes bis zur Nummer X empfangen."

Zum Beispiel:

Client envoie :

0 → 999

Serveur répond :

ACK = 1000

Das bedeutet:

"Alles vor Byte 1000 ist gut angekommen."

Dieser Mechanismus erlaubt es, mehrere Segmente auf einmal zu bestätigen (cumulative acknowledgments) und so die Zahl der Kontrollpakete zu reduzieren.

Die Retransmissionen

Wenn ein ACK nie ankommt, nimmt TCP an, dass das Segment verloren ist.

Es überträgt es automatisch erneut.

Die Retransmissionsverzögerung (Retransmission Timeout, RTO) ist nicht fest.

TCP misst permanent die Round-Trip-Zeit (RTT) dank der empfangenen ACKs und berechnet den RTO dynamisch, um unnötige Retransmissionen zu vermeiden.

Moderne Implementierungen nutzen auch Mechanismen wie Fast Retransmit: Wenn ein Sender mehrere duplizierte ACKs empfängt (generell drei), folgert er, dass ein Zwischensegment verloren ging, und schickt es sofort erneut, ohne auf den Ablauf des Timers zu warten.

Reorganisation der Pakete

Das Internet garantiert absolut nicht, dass zwei Pakete demselben Pfad folgen.

Beispiel:

Paquet 1
Paris
  ↓
Londres
  ↓
New York

Paquet 2
Paris
  ↓
Francfort
  ↓
Chicago
  ↓
New York

Das zweite Paket kann vor dem ersten ankommen.

TCP speichert dann temporär die außer der Reihe empfangenen Segmente in einem Puffer (reassembly buffer) und baut sie wieder zusammen, bevor es sie an die Anwendung liefert.

Für die Anwendung scheint alles perfekt der Reihe nach anzukommen.

Flusskontrolle

Eine Verbindung hängt nicht nur vom Netz ab.

Der Empfänger besitzt ebenfalls begrenzte Speicherkapazität.

Wenn er schneller empfängt, als er die Daten verarbeiten kann, sättigen sich seine Buffer irgendwann.

TCP löst dieses Problem dank eines gleitenden Fensters (Sliding Window).

Der Empfänger gibt in jedem ACK an:

Window = 32768 octets

Das bedeutet:

"Du kannst mir bis zu 32 Ko zusätzlich schicken."

Wenn dieses Fenster auf null fällt:

Window = 0

setzt der Sender die Übertragungen temporär aus, bis der Empfänger ein neues verfügbares Fenster ankündigt.

Dieser Mechanismus bildet die Flusskontrolle (Flow Control) und verhindert, dass ein schneller Host einen langsameren Host flutet.

Überlastungskontrolle

Selbst wenn der Empfänger die Daten absorbieren kann, kann das Netz selbst gesättigt werden.

Router verfügen über begrenzte Warteschlangen (queues).

Wenn sie überlaufen, werden die Pakete verworfen.

TCP interpretiert Verluste als Überlastungszeichen und passt seinen Durchsatz automatisch dank eines Überlastungsfensters (Congestion Window, cwnd) an.

Moderne Algorithmen (wie Reno, CUBIC oder BBR, je nach Betriebssystem) justieren dieses Fenster, um ein Gleichgewicht zwischen maximalem Durchsatz und Netzstabilität zu finden.

Die ersten TCP-Versionen nutzten hauptsächlich zwei Mechanismen:

  • Slow Start: Exponentielle Durchsatzsteigerung bis zur Erkennung einer Überlastung.

  • Congestion Avoidance: Danach vorsichtigere, generell lineare Steigerung.

Diese permanente Anpassung ist einer der Gründe, warum TCP trotz schwankender Netzqualität leistungsfähig bleibt.

Verbindungsabbau

Im Gegensatz zu UDP besitzt eine TCP-Verbindung auch einen sauberen Abbau.

Jedes Ende schließt unabhängig seinen Strom dank des FIN-Flags.

Ein kompletter Abbau erfordert generell vier Austausche:

FIN
ACK
FIN
ACK

Diese Prozedur garantiert, dass alle transitierenden Daten gut geliefert wurden, bevor die Verbindung zerstört wird.

UDP: maximale Einfachheit

UDP (User Datagram Protocol) verfolgt die inverse Philosophie.

Es ist verbindungslos (connectionless).

Es gibt:

  • keinen Handshake;

  • keine Sequenznummer;

  • keine Empfangsbestätigung;

  • keine Retransmission;

  • keine Flusskontrolle;

  • keine Überlastungskontrolle.

Jede Nachricht wird einfach in ein unabhängiges Datagramm verpackt, ans Netz übergeben und dann vom Sender vergessen.

Application → Datagramme UDP → IP → Internet

Das Protokoll bewahrt keinen Zustand zwischen zwei Sendungen.

Jedes Datagramm ist völlig unabhängig von den vorherigen.

Die Datenintegrität

Obwohl UDP weder Lieferung noch Reihenfolge garantiert, schützt es trotzdem die Datenintegrität dank einer Checksumme.

Beim Empfang wird die Checksumme neu berechnet.

  • Wenn die Werte übereinstimmen, wird das Datagramm akzeptiert.

  • Sonst wird es sofort verworfen.

UDP erkennt also korrupte Daten, versucht aber nie, sie wiederherzustellen.

Warum ist UDP so schnell?

Der UDP-Header enthält nur 8 Bytes, gegen mindestens 20 Bytes für TCP (ohne Optionen wie Timestamps, SACK oder Window Scaling zu zählen).

Da keine Verbindung gehalten wird, muss das Betriebssystem den Zustand jedes Austauschs nicht verfolgen, was auch Speicherverbrauch und Verarbeitungskosten reduziert.

Die Anwendung empfängt die Daten quasi sobald sie ankommen, ohne auf eventuelle Retransmissionen zu warten.

Wenn Datenverlust vorzuziehen ist

Die Grundidee ist simpel:

Eine alte Information kann weniger Wert haben als eine verlorene Information.

Nehmen wir ein VoIP-Gespräch.

Jedes Paket transportiert etwa 20 ms Stimme.

Wenn ein Paket verloren geht, würde seine Retransmission oft länger dauern als diese 20 ms.

Wenn es endlich ankäme, wäre das Gespräch schon weiter.

Die meisten Anwendungen ziehen dann vor, den Verlust zu maskieren (Interpolation, Stille, Fehlerkorrektur), statt auf die Retransmission zu warten.

Dieselbe Überlegung gilt für:

  • Echtzeit-Multiplayerspiele;

  • Videostreaming;

  • Telemetrieströme;

  • IoT-Sensoren;

  • GPS-Positionsdaten.

Ein aktueller Wert ist fast immer nützlicher als ein alter perfekt zuverlässiger Wert.

Ebene 2: die Verschlüsselung, TLS

TLS (Transport Layer Security, Nachfolger von SSL) ersetzt TCP nicht, es kommt obendrauf. Konkret baut TLS eine normale TCP-Verbindung auf und verhandelt dann darin eine verschlüsselte Session: Zertifikatsaustausch, Einigung auf einen Verschlüsselungsalgorithmus, Ableitung von Session-Schlüsseln. Alles, was danach transitiert, ist verschlüsselt und authentifiziert.

Drei unterschiedliche, oft verwechselte Garantien:

  • Vertraulichkeit: Niemand außer den zwei Parteien kann den Inhalt lesen.

  • Integrität: Jede Veränderung der Daten im Transit wird erkannt.

  • Authentifizierung: Aber im klassischen TLS einseitig: Der Client prüft, dass der Server wirklich der ist, für den er sich ausgibt (via sein Zertifikat, signiert von einer vertrauenswürdigen Autorität), aber der Server prüft nichts über die Clientidentität. Das ist exakt das HTTPS-Modell, wenn du eine Seite besuchst: Der Browser authentifiziert die Seite, die Seite authentifiziert dich nicht (die Nutzerauthentifizierung läuft über einen separaten Mechanismus, Session-Cookie, Token).

TLS 1.3 (die aktuell empfohlene Version) hat den Handshake im Normalfall auf einen einzigen Round-Trip reduziert, gegen zwei bei TLS 1.2, was die Verbindungslatenz spürbar senkt.

Ebene 2bis: mTLS, die Authentifizierung wird gegenseitig

mTLS (mutual TLS) ist TLS mit einer zusätzlichen Bedingung: Der Server verlangt auch ein Zertifikat vom Client und prüft es. Beide Parteien beweisen ihre Identität via ein von einer gemeinsamen vertrauenswürdigen Autorität signiertes Zertifikat.

Das ist der natürliche Mechanismus für Service-zu-Service-Kommunikation in einer verteilten Architektur: Wo klassisches HTTPS reicht, damit ein Browser mit einem öffentlichen Server redet, beantwortet mTLS eine andere Frage; woher weiß ein interner Service, dass er wirklich mit einem anderen autorisierten internen Service redet und nicht mit einem Angreifer, der im Netz gelandet wäre ?

Client                                          Serveur
  │──── ClientHello ─────────────────────────────▶│
  │◀─── ServerHello + certificat serveur ──────────│
  │──── vérifie le certificat serveur ─────────────│
  │──── envoie SON PROPRE certificat client ──────▶│
  │◀─── vérifie le certificat client ───────────────│
  │──── clés de session dérivées, canal chiffré ──▶│

Die Kehrseite von mTLS ist operativ: Man braucht eine interne Zertifizierungsautorität (CA), einen Verteilmechanismus der Zertifikate an jeden Service und eine Rotations-/Revokationsstrategie. In einer Single-Machine-Umgebung mit wenigen Services ist das manchmal mehr Komplexität als Nutzen, mTLS wird notwendig ab dem Moment, wo der Inter-Service-Traffic ein Netz durchquert, das man nicht vollständig kontrolliert (mehrere Hosts, Multi-Tenant-Cloud), oder sobald man eine Policy vom Typ Zero Trust will, wo kein Service implizit vertrauenswürdig ist, bloß weil er "drinnen" im Netz ist.

Ebene 3: die Anwendungsprotokolle über TCP+TLS

Sobald Transport und Verschlüsselung stehen, bleibt zu definieren, wie man die Austausche strukturiert. Das ist die Rolle der Anwendungsprotokolle.

HTTP / HTTPS

HTTP ist ein Request-Response-Protokoll: Der Client öffnet eine Verbindung (oder nutzt eine wieder, mit Keep-Alive), schickt eine Anfrage, wartet auf eine Antwort, die Verbindung kann sich danach schließen oder wiederverwendet werden. HTTPS ist schlicht HTTP über TLS, das S ändert nichts an der Protokollsemantik, nur daran, dass der Transport verschlüsselt ist.

Das Request-Response-Modell hat eine strukturelle Grenze: Der Server kann nie zuerst reden. Er kann nur auf das antworten, was der Client fragt. Für häufiges Polling ("gibt es was Neues ?" jede Sekunde) geht das, verschwendet aber Ressourcen, jede Anfrage erzeugt Protokolloverhead, um meistens nichts Neues anzukündigen.

WebSocket (WS / WSS)

WebSocket beantwortet genau diese Grenze. Die Verbindung startet wie eine klassische HTTP-Anfrage (mit einem Upgrade: websocket-Header), aber sobald der Handshake akzeptiert ist, ist die darunterliegende TCP-Verbindung kein HTTP-Request-Response-Kanal mehr, sie wird ein bidirektionaler Full-Duplex-Kanal, wo Client und Server jederzeit Nachrichten schicken können, ohne bei jedem Austausch einen Request-Response-Zyklus neu ausstoßen zu müssen.

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

WSS ist schlicht WebSocket über TLS, exakt wie HTTPS HTTP über TLS ist. Es ist das Protokoll der Wahl für alles, was Server-Push in Echtzeit braucht, Chat, Notifications, Trading-Ströme, Spiel-Events, ohne selbst ein Binärprotokoll über nacktem TCP verwalten zu wollen.

gRPC

Weniger bekannt außerhalb der Microservices-Welt, aber zentral in Service-zu-Service-Kommunikation: gRPC baut auf HTTP/2 (also TCP + optionales TLS), serialisiert Nachrichten in Protocol Buffers (binär, typisiert, kompakt, im Gegensatz zum Text-JSON der meisten REST-APIs) und erlaubt nativ bidirektionales Streaming dank HTTP/2-Multiplexing (mehrere logische Ströme auf einer einzigen TCP-Verbindung, ohne das Head-of-Line-Blocking, das mehrere sequenzielle HTTP/1.1-Anfragen hätten).

QUIC / HTTP3

QUIC ändert die Spielregeln, indem es von UDP statt TCP auf Transportebene neu startet und darüber die Zuverlässigkeitsgarantien reimplementiert, die TCP nativ bot, aber Strom für Strom statt global, was das Head-of-Line-Blocking auf Transportebene eliminiert (ein verlorenes Paket auf einem Strom blockiert nicht mehr die anderen Ströme derselben Verbindung). TLS 1.3 ist direkt in QUIC integriert statt obendrauf gelegt, was die Handshakelatenz weiter senkt. HTTP/3 ist HTTP über QUIC.

Überblick: wo jedes Protokoll liegt

Schicht Protokolle Rolle Transport TCP, UDP Bytes reisen lassen, zuverlässig oder nicht Transport (neue Generation) QUIC UDP + Zuverlässigkeit pro Strom + integriertes TLS Sicherheit TLS, mTLS Verschlüsselung, Integrität, Authentifizierung (uni oder gegenseitig) Anwendung HTTP/HTTPS, WS/WSS, gRPC Austausche strukturieren (Request-Response, bidirektional, typisiertes RPC)

Ein konkretes Beispiel, um die Ideen zu fixieren: Eine Microservices-Architektur mit Webdashboard und internen Services könnte vernünftigerweise HTTPS (Dashboard ↔ öffentliche API, einseitige Authentifizierung browser-seitig ausreichend), mTLS (Service ↔ Service intern, gegenseitige Authentifizierung nötig) und WSS (Echtzeit-Notifications ans Dashboard gepusht) kombinieren, drei unterschiedliche Anwendungsprotokolle, alle auf demselben TCP + TLS-Sockel gebaut.

Wie man in der Praxis wählt

Drei Fragen reichen generell, um zu entscheiden:

  1. Brauche ich Zuverlässigkeit und Reihenfolge, oder geht Datenfrische vor garantierter Lieferung ? → TCP wenn ja, UDP wenn nein (oder QUIC, um beides zugleich über einen anderen Kompromiss zu haben).

  2. Muss der Server Nachrichten initiieren können, oder stellt der Client immer die erste Anfrage ? → WebSocket/gRPC-Streaming, wenn der Server pushen muss, sonst klassisches HTTP.

  3. Müssen beide Parteien gegenseitig ihre Identität beweisen, oder muss nur eine der beiden verifiziert werden ? → mTLS für Service-zu-Service in Zero-Trust-Umgebung, simples TLS für klassischen öffentlichen Client.

Die operative Komplexität steigt mit jeder hinzugefügten Schicht, nacktes TCP hat keine zu verwaltende Infrastruktur, TLS verlangt Zertifikate, mTLS verlangt eine CA und eine Rotationsstrategie, gRPC verlangt eine geteilte Protobuf-Schemadefinition. Der gute Reflex ist, nur in Komplexität aufzusteigen, wenn die darunterliegende Schicht eine konkrete Grenze zeigt, nicht in Antizipation.

Как машины говорят друг с другом : обзор от TCP до mTLS

Почему TCP, UDP, TLS, mTLS, HTTP и WebSocket не конкурирующие альтернативы, а сложенные слои; иерархический обзор коммуникации машина-машина, от сырого транспорта до взаимной аутентификации.

Проблема : слишком много аббревиатур, мало иерархии

TCP, UDP, TLS, mTLS, WebSocket, HTTP, HTTPS, gRPC, QUIC; большинство ресурсов про них подают их как плоский список взаимозаменяемых опций, "выбирать по юзкейсу". В реальности они не на одном уровне : одни транспортные протоколы, другие слои безопасности, оборачивающиеся вокруг транспорта, третьи прикладные протоколы, опирающиеся на первые два. Понять иерархию значит понять, почему никогда не "выбирают" между TCP и TLS : выбирают TCP, потом решают, класть ли сверху TLS.

Эта статья перестраивает эту иерархию слой за слоем, от сырого транспорта до взаимной аутентификации, с для каждого уровня : что он гарантирует, чего не гарантирует и когда им довольствоваться.

Уровень 1 : транспорт (TCP против UDP)

Всё начинается здесь. TCP и UDP два главных протокола уровня Transport (Layer 4) модели OSI. Их роль одинакова : переносить поток данных между двумя приложениями, выполняющимися на разных машинах. Однако способ достичь этого радикально разный.

Важно понимать, что IP (Internet Protocol) на сетевом уровне (Layer 3) лишь маршрутизирует пакеты от хоста к хосту. Он не гарантирует ни их прибытия, ни порядка, ни даже уникальности. Роутеры просто принимают независимые решения о маршрутизации для каждого пакета.

Именно это отсутствие гарантий TCP и приходит компенсировать, а UDP осознанно выбирает ничего не добавлять, чтобы оставаться экстремально лёгким.

TCP : надёжность прежде всего

TCP (Transmission Control Protocol) это протокол ориентированный на соединение (connection-oriented). Прежде чем обменять хоть байт данных, обе машины должны установить логическое соединение.

Это соединение создаётся знаменитым трёхсторонним хендшейком :


Клиент                          Сервер
SYN ---------------------------->
        <--------------------- SYN + ACK
ACK ---------------------------->
Соединение установлено

Каждый шаг имеет точную цель :

  • SYN : клиент объявляет, что хочет открыть соединение, и даёт первый порядковый номер (Initial Sequence Number - ISN).

  • SYN-ACK : сервер принимает соединение, подтверждает получение SYN и в свою очередь даёт собственный порядковый номер.

  • ACK : клиент подтверждает получение информации сервера.

С этого момента обе машины знают состояние соединения и могут начинать обмен данными.

Порядковые номера

TCP видит данные не как очередь пакетов, а как непрерывный поток байтов (byte stream).

У каждого отправленного байта есть порядковый номер.

Пример :

Сообщение :

Bonjour

B = байт 0
o = байт 1
n = байт 2
...

Если сегмент, содержащий байты 1000-1499, потерян при транспортировке, получатель может детектировать ровно, чего не хватает.

Отправитель переотправляет только эту порцию.

Эта гранулярность одна из причин робастности TCP.

Подтверждения (ACK)

После приёма данных получатель отправляет ACK (Acknowledgment).

Вопреки тому, что часто воображают, ACK не значит :

"Я получил этот пакет"

Он скорее значит :

"Я получил все байты вплоть до номера X."

Например :

Клиент отправляет :

0 → 999

Сервер отвечает :

ACK = 1000

Это значит :

"Всё до байта 1000 дошло нормально."

Этот механизм позволяет подтверждать несколько сегментов сразу (cumulative acknowledgments), снижая число контрольных пакетов.

Переотправки

Если ACK так и не приходит, TCP предполагает, что сегмент потерян.

Он автоматически его переотправляет.

Задержка переотправки (Retransmission Timeout – RTO) не фиксирована.

TCP постоянно измеряет время туда-обратно (RTT) по полученным ACK и динамически вычисляет RTO, чтобы избегать бесполезных переотправок.

Современные реализации используют также механизмы вроде Fast Retransmit : когда отправитель получает несколько дублированных ACK (обычно три), он выводит, что промежуточный сегмент потерян, и шлёт его сразу, не дожидаясь истечения таймера.

Переупорядочивание пакетов

Интернет совершенно не гарантирует, что два пакета пойдут одним путём.

Пример :

Пакет 1
Париж
  ↓
Лондон
  ↓
Нью-Йорк

Пакет 2
Париж
  ↓
Франкфурт
  ↓
Чикаго
  ↓
Нью-Йорк

Второй пакет может прийти раньше первого.

TCP тогда временно хранит полученные вне порядка сегменты в буфере (reassembly buffer), затем пересобирает их, прежде чем отдать приложению.

Для приложения всё выглядит приходящим идеально по порядку.

Контроль потока

Соединение зависит не только от сети.

У получателя тоже ограниченная память.

Если он получает быстрее, чем может обрабатывать данные, его буферы в итоге насыщаются.

TCP решает эту проблему через скользящее окно (Sliding Window).

Получатель указывает в каждом ACK :

Window = 32768 байтов

Это значит :

"Можешь слать мне до 32 КБ дополнительно."

Если это окно падает до нуля :

Window = 0

Отправитель временно приостанавливает передачи, пока получатель не объявит новое доступное окно.

Этот механизм составляет контроль потока (Flow Control) и не даёт быстрому хосту затопить более медленный.

Контроль перегрузки

Даже если получатель способен поглощать данные, сама сеть может стать насыщенной.

У роутеров ограниченные очереди (queues).

Когда они переполняются, пакеты отбрасываются.

TCP интерпретирует потери как признак перегрузки и автоматически адаптирует свою скорость через окно перегрузки (Congestion Window – cwnd).

Современные алгоритмы (вроде Reno, CUBIC или BBR, в зависимости от ОС) подстраивают это окно, чтобы найти баланс между максимальной пропускной способностью и стабильностью сети.

Первые версии TCP использовали в основном два механизма :

  • Slow Start : экспоненциальный рост скорости до детекта перегрузки.

  • Congestion Avoidance : затем более осторожный, обычно линейный рост.

Эта постоянная адаптация одна из причин, почему TCP остаётся производительным несмотря на вариации качества сети.

Закрытие соединения

В отличие от UDP, TCP-соединение имеет и чистое закрытие.

Каждый конец независимо закрывает свой поток флагом FIN.

Полное закрытие обычно требует четырёх обменов :

FIN
ACK
FIN
ACK

Эта процедура гарантирует, что все данные в пути были доставлены до разрушения соединения.

UDP : максимальная простота

UDP (User Datagram Protocol) исповедует обратную философию.

Он без соединения (connectionless).

Нет :

  • никакого хендшейка ;

  • никаких порядковых номеров ;

  • никаких подтверждений ;

  • никаких переотправок ;

  • никакого контроля потока ;

  • никакого контроля перегрузки.

Каждое сообщение просто инкапсулируется в независимую дейтаграмму, передаётся сети, затем забывается отправителем.

Приложение → Дейтаграмма UDP → IP → Интернет

Протокол не хранит состояния между двумя отправками.

Каждая дейтаграмма полностью независима от предыдущих.

Целостность данных

Хотя UDP не гарантирует ни доставку, ни порядок, он всё же защищает целостность данных через контрольную сумму.

При приёме контрольная сумма пересчитывается.

  • Если значения совпадают, дейтаграмма принимается.

  • Иначе она сразу отбрасывается.

UDP, таким образом, детектирует повреждённые данные, но никогда не пытается их восстанавливать.

Почему UDP такой быстрый?

Заголовок UDP содержит всего 8 байтов против минимум 20 байтов у TCP (не считая опций вроде timestamps, SACK или Window Scaling).

Раз соединение не держится, ОС не надо отслеживать состояние каждого обмена, что снижает потребление памяти и стоимость обработки.

Приложение получает данные почти сразу по прибытии, не дожидаясь возможных переотправок.

Когда потеря данных предпочтительна

Фундаментальная идея проста :

Une information ancienne peut avoir moins de valeur qu'une information perdue.

Возьмём разговор VoIP.

Каждый пакет несёт около 20 мс голоса.

Если пакет потерян, его переотправка часто заняла бы больше этих 20 мс.

Когда бы он наконец пришёл, разговор уже ушёл бы вперёд.

Большинство приложений предпочитают маскировать потерю (интерполяция, тишина, коррекция ошибок), а не ждать переотправки.

То же рассуждение применимо :

  • многопользовательским играм реального времени ;

  • видеосримингу ;

  • потокам телеметрии ;

  • IoT-датчикам ;

  • данным GPS-позиции.

Свежее значение почти всегда полезнее старого, но идеально надёжного.

Уровень 2 : шифрование, TLS

TLS (Transport Layer Security, преемник SSL) не заменяет TCP, он добавляется сверху. Конкретно TLS устанавливает нормальное TCP-соединение, затем договаривается о шифрованной сессии внутри : обмен сертификатами, согласование алгоритма шифрования, вывод сессионных ключей. Всё, что идёт дальше, шифруется и аутентифицируется.

Три отдельные гарантии, часто смешиваемые :

  • Конфиденциальность : никто, кроме двух сторон, не может читать содержимое.

  • Целостность : любое изменение данных в пути детектируется.

  • Аутентификация : но в классическом TLS односторонняя : клиент проверяет, что сервер именно тот, за кого себя выдаёт (через свой сертификат, подписанный доверенным центром), а сервер ничего не проверяет про идентичность клиента. Это ровно модель HTTPS, когда ты заходишь на сайт : браузер аутентифицирует сайт, сайт тебя не аутентифицирует (аутентификация пользователя идёт через отдельный механизм, сессионный cookie, token).

TLS 1.3 (текущая рекомендуемая версия) ужала хендшейк до одного round-trip в обычном случае против двух у TLS 1.2, что заметно снижает задержку соединения.

Уровень 2bis : mTLS -- аутентификация становится взаимной

mTLS (mutual TLS) это TLS с дополнительным ограничением : сервер требует тоже сертификат клиента и проверяет его. Обе стороны доказывают идентичность через сертификат, подписанный общим доверенным центром.

Это естественный механизм для коммуникации сервис-сервис в распределённой архитектуре : там, где классического HTTPS достаточно, чтобы браузер говорил с публичным сервером, mTLS отвечает на другой вопрос; как внутренний сервис знает, что говорит именно с другим разрешённым внутренним сервисом, а не с атакующим, оказавшимся в сети?

Клиент                                         Сервер
  │──── ClientHello ─────────────────────────────▶│
  │◀─── ServerHello + сертификат сервера ──────────│
  │──── проверяет сертификат сервера ─────────────│
  │──── отправляет СВОЙ сертификат клиента ──────▶│
  │◀─── проверяет сертификат клиента ───────────────│
  │──── сессионные ключи выведены, канал шифрован ──▶│

Расплата за mTLS операционная : нужен внутренний центр сертификации (CA), механизм раздачи сертификатов каждому сервису и стратегия ротации/отзыва. В моно-машинном окружении с малым числом сервисов это порой больше сложности, чем выгоды -- mTLS становится нужен с момента, когда межсервисный трафик идёт через сеть, контролируемую не полностью (несколько хостов, мультитенантный cloud), или как только хочешь политику типа zero trust, где ни один сервис не достоин доверия имплицитно просто потому, что он "внутри" сети.

Уровень 3 : прикладные протоколы поверх TCP+TLS

Когда транспорт и шифрование на месте, остаётся определить как структурировать обмены. Это роль прикладных протоколов.

HTTP / HTTPS

HTTP это протокол запрос-ответ : клиент открывает соединение (или переиспользует его с keep-alive), шлёт запрос, ждёт ответ, соединение может затем закрыться или переиспользоваться. HTTPS это просто HTTP поверх TLS -- S ничего не меняет в семантике протокола, только в том, что транспорт шифрован.

У модели запрос-ответ структурный лимит : сервер никогда не может заговорить первым. Он может лишь отвечать на то, что просит клиент. Для частого polling ("есть новое?" каждую секунду) это работает, но тратит ресурсы -- каждый запрос пересоздаёт протокольный оверхед ради, чаще всего, отсутствия чего-то нового для объявления.

WebSocket (WS / WSS)

WebSocket отвечает ровно на этот лимит. Соединение стартует как классический HTTP-запрос (с заголовком Upgrade: websocket), но как только хендшейк принят, нижележащее TCP-соединение больше не канал запрос-ответ HTTP -- оно становится двунаправленным full-duplex каналом, где клиент и сервер могут слать сообщения в любой момент, без нужды перевыпускать цикл запрос-ответ при каждом обмене.

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

WSS это просто WebSocket поверх TLS, ровно как HTTPS это HTTP поверх TLS. Это протокол выбора для всего, где нужен серверный push в реальном времени -- чат, уведомления, потоки трейдинга, игровые события -- без желания самому рулить бинарным протоколом поверх голого TCP.

gRPC

Менее известен вне мира микросервисов, но централен в коммуникации сервис-сервис : gRPC опирается на HTTP/2 (то есть TCP + опциональный TLS), сериализует сообщения в Protocol Buffers (бинарный, типизированный, компактный -- в отличие от текстового JSON большинства REST API) и нативно позволяет двунаправленный стриминг благодаря мультиплексированию HTTP/2 (несколько логических потоков на одном TCP-соединении без head-of-line blocking, какой был бы у нескольких последовательных запросов HTTP/1.1).

QUIC / HTTP3

QUIC меняет правила, стартуя с UDP вместо TCP на транспортном уровне, перереализуя сверху гарантии надёжности, что TCP давал нативно, -- но поток за потоком, а не глобально, что убирает head-of-line blocking на транспортном уровне (потерянный пакет на одном потоке больше не блокирует другие потоки того же соединения). TLS 1.3 встроен прямо в QUIC, а не добавлен сверху, что ещё снижает задержку хендшейка. HTTP/3 это HTTP поверх QUIC.

Обзор : где находится каждый протокол

Слой Протоколы Роль Транспорт TCP, UDP Гонять байты, надёжно или нет Транспорт (новое поколение) QUIC UDP + надёжность по потокам + встроенный TLS Безопасность TLS, mTLS Шифрование, целостность, аутентификация (одно- или взаимная) Прикладной HTTP/HTTPS, WS/WSS, gRPC Структурировать обмены (запрос-ответ, двунаправленный, типизированный RPC)

Конкретный пример, чтобы зафиксировать идеи : архитектура микросервисов с веб-дашбордом и внутренними сервисами могла бы разумно комбинировать HTTPS (дашборд ↔ публичный API, односторонней аутентификации достаточно со стороны браузера), mTLS (сервис ↔ сервис внутри, нужна взаимная аутентификация) и WSS (пуш уведомлений реального времени в дашборд) -- три разных прикладных протокола, все построенные на том же фундаменте TCP + TLS.

Как выбирать на практике

Трёх вопросов обычно достаточно, чтобы решить :

  1. Нужны ли мне надёжность и порядок, или свежесть данных важнее гарантированной доставки? → TCP если да, UDP если нет (или QUIC, чтобы иметь оба сразу через другой компромисс).

  2. Должен ли сервер уметь инициировать сообщения, или клиент всегда делает первый запрос? → WebSocket/gRPC streaming если сервер должен пушить, классический HTTP иначе.

  3. Должны ли обе стороны взаимно доказывать идентичность, или проверяться нужно только одной? → mTLS для сервис-сервис в окружении zero-trust, простой TLS для классического публичного клиента.

Операционная сложность растёт с каждым добавленным слоем, голый TCP не имеет инфраструктуры для управления, TLS требует сертификатов, mTLS требует CA и стратегии ротации, gRPC требует общего определения схемы Protobuf. Правильный рефлекс подниматься в сложности, только когда нижний слой показывает конкретный лимит, а не впрок.

Cómo hablan las máquinas: un recorrido de TCP a mTLS

Por qué TCP, UDP, TLS, mTLS, HTTP y WebSocket no son alternativas competidoras sino capas apiladas; un recorrido jerárquico de la comunicación máquina a máquina, del transporte en bruto a la autenticación mutua.

El problema: demasiadas siglas, poca jerarquía

TCP, UDP, TLS, mTLS, WebSocket, HTTP, HTTPS, gRPC, QUIC; la mayoría de los recursos que hablan de ellos los presentan como una lista plana de opciones intercambiables, "a elegir según el caso de uso". En realidad no están en el mismo plano: algunos son protocolos de transporte, otros capas de seguridad que se enrollan alrededor del transporte, otros aún protocolos aplicativos que se apoyan en los dos primeros. Entender la jerarquía es entender por qué nunca "eliges" entre TCP y TLS: eliges TCP, y luego decides si pones TLS encima.

Este artículo reconstruye esa jerarquía capa por capa, del transporte en bruto hasta la autenticación mutua, con para cada nivel: lo que garantiza, lo que no garantiza, y cuándo conformarse con él.

Nivel 1: el transporte (TCP contra UDP)

Todo empieza aquí. TCP y UDP son los dos principales protocolos de la capa Transporte (Layer 4) del modelo OSI. Su rol es idéntico: transportar un flujo de datos entre dos aplicaciones ejecutadas en máquinas distintas. Sin embargo, su forma de lograrlo es radicalmente distinta.

Es importante entender que IP (Internet Protocol), situado en la capa red (Layer 3), solo encamina paquetes de un anfitrión a otro. No garantiza ni su llegada, ni su orden, ni siquiera su unicidad. Los routers simplemente toman decisiones de ruteo independientes para cada paquete.

Es justo esa ausencia de garantías la que TCP viene a compensar, mientras UDP elige deliberadamente no añadir nada para seguir siendo extremadamente ligero.

TCP: la fiabilidad ante todo

TCP (Transmission Control Protocol) es un protocolo orientado a conexión (connection-oriented). Antes de intercambiar el menor byte de datos, ambas máquinas tienen que establecer una conexión lógica.

Esa conexión se crea gracias al famoso Three-Way Handshake:


Client                           Serveur
SYN ---------------------------->
        <--------------------- SYN + ACK
ACK ---------------------------->
Connexion établie

Cada etapa tiene un objetivo preciso:

  • SYN: el cliente anuncia que desea abrir una conexión y aporta un primer número de secuencia (Initial Sequence Number - ISN).

  • SYN-ACK: el servidor acepta la conexión, acusa recibo del SYN y aporta a su vez su propio número de secuencia.

  • ACK: el cliente confirma la recepción de la información del servidor.

A partir de ese momento, ambas máquinas conocen el estado de la conexión y pueden empezar a intercambiar datos.

Los números de secuencia

TCP no ve los datos como una sucesión de paquetes, sino como un flujo continuo de bytes (byte stream).

Cada byte enviado tiene un número de secuencia.

Ejemplo:

Message :

Bonjour

B = octet 0
o = octet 1
n = octet 2
...

Si un segmento con los bytes 1000 a 1499 se pierde durante el transporte, el receptor puede detectar exactamente qué falta.

El emisor retransmite solo esa porción.

Esa granularidad es una de las razones de la robustez de TCP.

Los acuses de recibo (ACK)

Tras recibir los datos, el destinatario envía un ACK (Acknowledgment).

Al contrario de lo que suele imaginarse, un ACK no significa:

"Recibí ese paquete"

Más bien significa:

"Recibí todos los bytes hasta el número X."

Por ejemplo:

Client envoie :

0 → 999

Serveur répond :

ACK = 1000

Eso significa:

"Todo lo anterior al byte 1000 llegó bien."

Ese mecanismo permite acusar recibo de varios segmentos a la vez (cumulative acknowledgments), reduciendo así el número de paquetes de control.

Las retransmisiones

Si un ACK nunca llega, TCP supone que el segmento se perdió.

Lo retransmite automáticamente.

El retardo de retransmisión (Retransmission Timeout – RTO) no es fijo.

TCP mide permanentemente el tiempo de ida y vuelta (RTT) gracias a los ACK recibidos y calcula dinámicamente el RTO para evitar retransmisiones inútiles.

Las implementaciones modernas también usan mecanismos como Fast Retransmit: cuando un emisor recibe varios ACK duplicados (generalmente tres), deduce que un segmento intermedio se perdió y lo reenvía de inmediato, sin esperar a que expire el temporizador.

Reordenación de los paquetes

Internet no garantiza en absoluto que dos paquetes sigan el mismo camino.

Ejemplo:

Paquet 1
Paris
  ↓
Londres
  ↓
New York

Paquet 2
Paris
  ↓
Francfort
  ↓
Chicago
  ↓
New York

El segundo paquete puede llegar antes que el primero.

TCP almacena entonces temporalmente los segmentos recibidos fuera de orden en un búfer (reassembly buffer), y luego los reensambla antes de entregarlos a la aplicación.

Para la aplicación, todo parece llegar perfectamente en orden.

Control de flujo

Una conexión no depende solo de la red.

El receptor también tiene una capacidad de memoria limitada.

Si recibe más rápido de lo que puede procesar los datos, sus búferes terminan saturándose.

TCP resuelve ese problema gracias a una ventana deslizante (Sliding Window).

El receptor indica en cada ACK:

Window = 32768 octets

Eso significa:

"Puedes enviarme hasta 32 KB adicionales."

Si esa ventana cae a cero:

Window = 0

El emisor suspende temporalmente las transmisiones hasta que el receptor anuncie una nueva ventana disponible.

Ese mecanismo constituye el control de flujo (Flow Control) e impide que un anfitrión rápido inunde un anfitrión más lento.

Control de congestión

Aunque el receptor sea capaz de absorber los datos, la propia red puede saturarse.

Los routers disponen de colas (queues) limitadas.

Cuando se desbordan, los paquetes se descartan.

TCP interpreta las pérdidas como un signo de congestión y adapta automáticamente su caudal gracias a una ventana de congestión (Congestion Window – cwnd).

Los algoritmos modernos (como Reno, CUBIC o BBR, según los sistemas operativos) ajustan esa ventana para encontrar un equilibrio entre caudal máximo y estabilidad de la red.

Las primeras versiones de TCP usaban principalmente dos mecanismos:

  • Slow Start: aumento exponencial del caudal hasta detectar una congestión.

  • Congestion Avoidance: crecimiento luego más prudente, generalmente lineal.

Esa adaptación permanente es una de las razones por las que TCP sigue rindiendo pese a las variaciones de calidad de la red.

Cierre de conexión

Al contrario que UDP, una conexión TCP también tiene un cierre limpio.

Cada extremo cierra independientemente su flujo gracias a la bandera FIN.

Un cierre completo necesita generalmente cuatro intercambios:

FIN
ACK
FIN
ACK

Ese procedimiento garantiza que todos los datos en tránsito se entregaron bien antes de destruir la conexión.

UDP: la simplicidad máxima

UDP (User Datagram Protocol) adopta la filosofía inversa.

Es sin conexión (connectionless).

No existe:

  • ningún handshake;

  • ningún número de secuencia;

  • ningún acuse de recibo;

  • ninguna retransmisión;

  • ningún control de flujo;

  • ningún control de congestión.

Cada mensaje simplemente se encapsula en un datagrama independiente, se transmite a la red, y el emisor lo olvida.

Application → Datagramme UDP → IP → Internet

El protocolo no conserva ningún estado entre dos envíos.

Cada datagrama es totalmente independiente de los anteriores.

La integridad de los datos

Aunque UDP no garantiza ni la entrega ni el orden, aun así protege la integridad de los datos gracias a un checksum.

Al recibir, el checksum se recalcula.

  • Si los valores coinciden, el datagrama se acepta.

  • Si no, se rechaza de inmediato.

UDP detecta por tanto los datos corruptos, pero nunca intenta recuperarlos.

¿Por qué UDP es tan rápido?

La cabecera UDP solo contiene 8 bytes, contra un mínimo de 20 bytes para TCP (sin contar las opciones como timestamps, SACK o Window Scaling).

Como no se mantiene ninguna conexión, el sistema operativo no tiene que seguir el estado de cada intercambio, lo que también reduce el consumo de memoria y el coste de procesamiento.

La aplicación recibe los datos casi en cuanto llegan, sin esperar eventuales retransmisiones.

Cuándo perder un dato es preferible

La idea fundamental es simple:

Una información vieja puede tener menos valor que una información perdida.

Tomemos una conversación VoIP.

Cada paquete transporta unos 20 ms de voz.

Si un paquete se pierde, retransmitirlo a menudo tardaría más que esos 20 ms.

Cuando por fin llegara, la conversación ya habría avanzado.

La mayoría de las aplicaciones prefieren entonces enmascarar la pérdida (interpolación, silencio, corrección de error) en vez de esperar la retransmisión.

El mismo razonamiento se aplica:

  • a los juegos multijugador en tiempo real;

  • al streaming de vídeo;

  • a los flujos de telemetría;

  • a los sensores IoT;

  • a los datos de posición GPS.

Un valor reciente casi siempre es más útil que un valor viejo perfectamente fiable.

Nivel 2: el cifrado, TLS

TLS (Transport Layer Security, sucesor de SSL) no reemplaza TCP, se añade encima. En concreto, TLS establece una conexión TCP normal, y luego negocia una sesión cifrada dentro: intercambio de certificados, acuerdo sobre un algoritmo de cifrado, derivación de claves de sesión. Todo lo que transita después va cifrado y autenticado.

Tres garantías distintas, a menudo confundidas:

  • Confidencialidad: nadie más que ambas partes puede leer el contenido.

  • Integridad: cualquier alteración de los datos en tránsito se detecta.

  • Autenticación: pero en el TLS clásico, en un solo sentido: el cliente verifica que el servidor es bien quien dice ser (vía su certificado, firmado por una autoridad de confianza), pero el servidor no verifica nada sobre la identidad del cliente. Es exactamente el modelo de HTTPS cuando visitas un sitio: el navegador autentica el sitio, el sitio no te autentica (la autenticación de usuario pasa por un mecanismo separado, cookie de sesión, token).

TLS 1.3 (la versión actual recomendada) redujo el handshake a una sola ida y vuelta en el caso común, contra dos para TLS 1.2, lo que reduce sensiblemente la latencia de conexión.

Nivel 2bis: mTLS: la autenticación se vuelve mutua

mTLS (mutual TLS) es TLS con una restricción adicional: el servidor exige también un certificado del cliente, y lo verifica. Ambas partes prueban su identidad vía un certificado firmado por una autoridad de confianza común.

Es el mecanismo natural para la comunicación servicio a servicio en una arquitectura distribuida: donde HTTPS clásico basta para que un navegador hable con un servidor público, mTLS responde a una pregunta distinta; ¿cómo sabe un servicio interno que habla bien con otro servicio interno autorizado, y no con un atacante que habría aterrizado en la red?

Client                                          Serveur
  │──── ClientHello ─────────────────────────────▶│
  │◀─── ServerHello + certificat serveur ──────────│
  │──── vérifie le certificat serveur ─────────────│
  │──── envoie SON PROPRE certificat client ──────▶│
  │◀─── vérifie le certificat client ───────────────│
  │──── clés de session dérivées, canal chiffré ──▶│

La contrapartida de mTLS es operativa: hace falta una autoridad de certificación (CA) interna, un mecanismo de distribución de los certificados a cada servicio, y una estrategia de rotación/revocación. En un entorno monomáquina con pocos servicios, a veces es más complejidad que beneficio: mTLS se vuelve necesario a partir del momento en que el tráfico entre servicios atraviesa una red que no controlamos del todo (varios anfitriones, cloud multitenant), o en cuanto se quiere una política tipo zero trust, donde ningún servicio es implícitamente digno de confianza simplemente porque está "dentro" de la red.

Nivel 3: los protocolos aplicativos sobre TCP+TLS

Una vez el transporte y el cifrado en su sitio, queda definir cómo estructurar los intercambios. Ese es el rol de los protocolos aplicativos.

HTTP / HTTPS

HTTP es un protocolo petición-respuesta: el cliente abre una conexión (o reutiliza una, con el keep-alive), envía una petición, espera una respuesta, la conexión puede luego cerrarse o reutilizarse. HTTPS es simplemente HTTP sobre TLS: la S no cambia nada de la semántica del protocolo, solo el hecho de que el transporte va cifrado.

El modelo petición-respuesta tiene un límite estructural: el servidor nunca puede hablar primero. Solo puede responder a lo que el cliente pide. Para polling frecuente (comprobar "¿hay algo nuevo?" cada segundo), funciona pero desperdicia recursos: cada petición recrea overhead protocolar para, la mayoría de las veces, no tener nada nuevo que anunciar.

WebSocket (WS / WSS)

WebSocket responde exactamente a ese límite. La conexión arranca como una petición HTTP clásica (con una cabecera Upgrade: websocket), pero una vez aceptado el apretón de manos, la conexión TCP subyacente ya no es un canal petición-respuesta HTTP: se vuelve un canal bidireccional full-duplex donde cliente y servidor pueden enviar mensajes en cualquier momento, sin tener que reemitir un ciclo petición-respuesta en cada intercambio.

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

WSS es simplemente WebSocket sobre TLS, exactamente como HTTPS es HTTP sobre TLS. Es el protocolo de elección para todo lo que necesita push de servidor en tiempo real: chat, notificaciones, flujos de trading, eventos de juego, sin querer gestionar uno mismo un protocolo binario sobre TCP desnudo.

gRPC

Menos conocido fuera del mundo microservicios pero central en comunicación servicio a servicio: gRPC se apoya en HTTP/2 (o sea TCP + TLS opcional), serializa los mensajes en Protocol Buffers (binario, tipado, compacto, al contrario que el JSON texto de la mayoría de las API REST), y permite nativamente el streaming bidireccional gracias al multiplexado de HTTP/2 (varios flujos lógicos sobre una sola conexión TCP, sin el head-of-line blocking que tendrían varias peticiones HTTP/1.1 secuenciales).

QUIC / HTTP3

QUIC cambia las reglas repartiendo de UDP en vez de TCP a nivel transporte, reimplementando encima las garantías de fiabilidad que TCP ofrecía nativamente, pero flujo por flujo en vez de globalmente, lo que elimina el head-of-line blocking a nivel transporte (un paquete perdido en un flujo ya no bloquea los demás flujos de la misma conexión). TLS 1.3 va integrado directamente en QUIC en vez de añadido encima, lo que reduce aún más la latencia de handshake. HTTP/3 es HTTP sobre QUIC.

Vista de conjunto: dónde se sitúa cada protocolo

Capa Protocolos Rol Transporte TCP, UDP Hacer viajar bytes, fiable o no Transporte (nueva generación) QUIC UDP + fiabilidad por flujo + TLS integrado Seguridad TLS, mTLS Cifrado, integridad, autenticación (uni o mutua) Aplicación HTTP/HTTPS, WS/WSS, gRPC Estructurar los intercambios (petición-respuesta, bidireccional, RPC tipado)

Un ejemplo concreto para fijar las ideas: una arquitectura microservicios con un dashboard web y servicios internos podría razonablemente combinar HTTPS (dashboard ↔ API pública, autenticación unidireccional suficiente en el navegador), mTLS (servicio ↔ servicio en interno, autenticación mutua necesaria), y WSS (notificaciones en tiempo real empujadas hacia el dashboard): tres protocolos aplicativos distintos, todos construidos sobre el mismo zócalo TCP + TLS.

Cómo elegir, en la práctica

Tres preguntas suelen bastar para decidir:

  1. ¿Necesito fiabilidad y orden, o la frescura del dato prima sobre su entrega garantizada? → TCP si sí, UDP si no (o QUIC para tener ambas cosas a la vez vía un compromiso distinto).

  2. ¿El servidor debe poder iniciar mensajes, o el cliente siempre hace la primera petición? → WebSocket/gRPC streaming si el servidor debe empujar, HTTP clásico si no.

  3. ¿Ambas partes deben probarse mutuamente su identidad, o solo una de las dos necesita verificarse? → mTLS para servicio a servicio en entorno zero-trust, TLS simple para cliente público clásico.

La complejidad operativa aumenta con cada capa añadida, TCP desnudo no tiene ninguna infraestructura que gestionar, TLS pide certificados, mTLS pide una CA y una estrategia de rotación, gRPC pide una definición de esquema Protobuf compartida. El buen reflejo es no subir en complejidad más que cuando la capa de abajo muestra un límite concreto, no por anticipación.

Como as máquinas se comunicam: um panorama do TCP ao mTLS

Por que TCP, UDP, TLS, mTLS, HTTP e WebSocket não são alternativas concorrentes, mas camadas empilhadas; um panorama hierárquico da comunicação máquina a máquina, do transporte bruto à autenticação mútua.

O problema: muitas siglas, pouca hierarquia

TCP, UDP, TLS, mTLS, WebSocket, HTTP, HTTPS, gRPC, QUIC; a maioria dos recursos que falam sobre eles os apresentam como uma lista plana de opções intercambiáveis, "a escolher conforme o caso de uso". Na realidade, eles não estão no mesmo plano: alguns são protocolos de transporte, outros são camadas de segurança que se enrolam em torno do transporte, outros ainda são protocolos de aplicação que se apoiam nos dois primeiros. Compreender a hierarquia é compreender por que nunca se "escolhe" entre TCP e TLS: escolhe-se TCP, depois decide-se se coloca TLS por cima.

Este artigo reconstrói essa hierarquia camada por camada, do transporte bruto até a autenticação mútua, com para cada nível: o que ele garante, o que não garante, e quando se contentar com ele.

Nível 1: o transporte (TCP contra UDP)

Tudo começa aqui. TCP e UDP são os dois principais protocolos da camada Transporte (Camada 4) do modelo OSI. O papel deles é idêntico: transportar um fluxo de dados entre duas aplicações executadas em máquinas diferentes. No entanto, a maneira como fazem isso é radicalmente diferente.

É importante entender que o IP (Internet Protocol), situado na camada de rede (Camada 3), apenas encaminha pacotes de um host para outro. Ele não garante nem a chegada, nem a ordem, nem mesmo a unicidade deles. Os roteadores simplesmente tomam decisões de roteamento independentes para cada pacote.

É precisamente essa ausência de garantias que o TCP vem compensar, enquanto o UDP escolhe deliberadamente não adicionar nada para permanecer extremamente leve.

TCP: a confiabilidade acima de tudo

TCP (Transmission Control Protocol) é um protocolo orientado à conexão (connection-oriented). Antes de trocar o menor byte de dados, as duas máquinas devem estabelecer uma conexão lógica.

Essa conexão é criada através do famoso Three-Way Handshake:


Cliente                          Servidor
SYN ---------------------------->
        <--------------------- SYN + ACK
ACK ----------------------------> 
Conexão estabelecida

Cada etapa possui um objetivo preciso:

  • SYN: o cliente anuncia que deseja abrir uma conexão e fornece um primeiro número de sequência (Initial Sequence Number - ISN).

  • SYN-ACK: o servidor aceita a conexão, confirma o recebimento do SYN e fornece por sua vez seu próprio número de sequência.

  • ACK: o cliente confirma o recebimento das informações do servidor.

A partir desse momento, as duas máquinas conhecem o estado da conexão e podem começar a trocar dados.

Os números de sequência

O TCP não vê os dados como uma sucessão de pacotes, mas como um fluxo contínuo de bytes (byte stream).

Cada byte enviado possui um número de sequência.

Exemplo:

Mensagem:

Bonjour

B = byte 0
o = byte 1
n = byte 2
...

Se um segmento contendo os bytes 1000 a 1499 for perdido durante o transporte, o receptor pode detectar exatamente o que está faltando.

O emissor retransmite apenas essa parte.

Essa granularidade é uma das razões da robustez do TCP.

As confirmações de recebimento (ACK)

Após o recebimento dos dados, o destinatário envia um ACK (Acknowledgment).

Ao contrário do que se imagina frequentemente, um ACK não significa:

"Recebi este pacote"

Ele significa sim:

"Recebi todos os bytes até o número X."

Por exemplo:

Cliente envia:

0 → 999

Servidor responde:

ACK = 1000

Isso significa:

"Tudo o que precede o byte 1000 chegou bem."

Esse mecanismo permite confirmar o recebimento de vários segmentos de uma só vez (cumulative acknowledgments), reduzindo assim o número de pacotes de controle.

As retransmissões

Se um ACK nunca chega, o TCP assume que o segmento foi perdido.

Ele o retransmite automaticamente.

O tempo de retransmissão (Retransmission Timeout – RTO) não é fixo.

O TCP mede permanentemente o tempo de ida e volta (RTT) graças aos ACKs recebidos e calcula dinamicamente o RTO para evitar retransmissões desnecessárias.

As implementações modernas também utilizam mecanismos como Fast Retransmit: quando um emissor recebe vários ACKs duplicados (geralmente três), ele deduz que um segmento intermediário foi perdido e o reenvia imediatamente, sem esperar a expiração do temporizador.

Reorganização dos pacotes

A Internet não garante absolutamente que dois pacotes sigam o mesmo caminho.

Exemplo:

Pacote 1
Paris
 ↓
Londres
 ↓
Nova York

Pacote 2
Paris
 ↓
Frankfurt
 ↓
Chicago
 ↓
Nova York

O segundo pacote pode chegar antes do primeiro.

O TCP então armazena temporariamente os segmentos recebidos fora de ordem em um buffer (reassembly buffer), e depois os remonta antes de entregá-los à aplicação.

Para a aplicação, tudo parece chegar perfeitamente em ordem.

Controle de fluxo

Uma conexão não depende apenas da rede.

O receptor também possui uma capacidade de memória limitada.

Se ele receber mais rápido do que consegue processar os dados, seus buffers acabam saturando.

O TCP resolve esse problema através de uma janela deslizante (Sliding Window).

O receptor indica em cada ACK:

Window = 32768 bytes

Isso significa:

"Você pode me enviar até 32 KB adicionais."

Se essa janela cair para zero:

Window = 0

O emissor suspende temporariamente as transmissões até que o receptor anuncie uma nova janela disponível.

Esse mecanismo constitui o controle de fluxo (Flow Control) e impede que um host rápido inunde um host mais lento.

Controle de congestionamento

Mesmo que o receptor seja capaz de absorver os dados, a própria rede pode ficar saturada.

Os roteadores dispõem de filas de espera (queues) limitadas.

Quando transbordam, os pacotes são descartados.

O TCP interpreta as perdas como um sinal de congestionamento e adapta automaticamente sua taxa de transmissão através de uma janela de congestionamento (Congestion Window – cwnd).

Os algoritmos modernos (como Reno, CUBIC ou BBR, dependendo dos sistemas operacionais) ajustam essa janela para encontrar um equilíbrio entre taxa máxima e estabilidade da rede.

As primeiras versões do TCP utilizavam principalmente dois mecanismos:

  • Slow Start: aumento exponencial da taxa até detectar um congestionamento.

  • Congestion Avoidance: crescimento depois mais prudente, geralmente linear.

Essa adaptação permanente é uma das razões pelas quais o TCP permanece performático apesar das variações de qualidade da rede.

Fechamento de conexão

Ao contrário do UDP, uma conexão TCP também possui um fechamento adequado.

Cada extremidade fecha independentemente seu fluxo através da flag FIN.

Um fechamento completo geralmente requer quatro trocas:

FIN
ACK
FIN
ACK

Esse procedimento garante que todos os dados em trânsito foram entregues antes da destruição da conexão.

UDP: a simplicidade máxima

UDP (User Datagram Protocol) adota a filosofia inversa.

Ele é sem conexão (connectionless).

Não existe:

  • nenhum handshake;

  • nenhum número de sequência;

  • nenhuma confirmação de recebimento;

  • nenhuma retransmissão;

  • nenhum controle de fluxo;

  • nenhum controle de congestionamento.

Cada mensagem é simplesmente encapsulada em um datagrama independente, transmitida à rede, e depois esquecida pelo emissor.

Aplicação → Datagrama UDP → IP → Internet

O protocolo não mantém nenhum estado entre dois envios.

Cada datagrama é totalmente independente dos anteriores.

A integridade dos dados

Embora o UDP não garanta nem a entrega nem a ordem, ele ainda protege a integridade dos dados através de um checksum.

No recebimento, o checksum é recalculado.

  • Se os valores coincidirem, o datagrama é aceito.

  • Caso contrário, é imediatamente rejeitado.

O UDP detecta portanto os dados corrompidos, mas nunca tenta recuperá-los.

Por que o UDP é tão rápido?

O cabeçalho UDP contém apenas 8 bytes, contra um mínimo de 20 bytes para o TCP (sem contar as opções como timestamps, SACK ou Window Scaling).

Nenhuma conexão sendo mantida, o sistema operacional não precisa acompanhar o estado de cada troca, o que também reduz o consumo de memória e o custo de processamento.

A aplicação recebe os dados quase que imediatamente após sua chegada, sem esperar por eventuais retransmissões.

Quando perder um dado é preferível

A ideia fundamental é simples:

Uma informação antiga pode ter menos valor do que uma informação perdida.

Vamos pegar uma conversa VoIP.

Cada pacote transporta aproximadamente 20 ms de voz.

Se um pacote for perdido, retransmiti-lo levaria muitas vezes mais tempo do que esses 20 ms.

Quando finalmente chegasse, a conversa já teria avançado.

A maioria das aplicações prefere então mascarar a perda (interpolação, silêncio, correção de erro) a esperar a retransmissão.

O mesmo raciocínio se aplica:

  • a jogos multijogador em tempo real;

  • ao streaming de vídeo;

  • a fluxos de telemetria;

  • a sensores IoT;

  • a dados de posição GPS.

Um valor recente é quase sempre mais útil do que um valor antigo perfeitamente confiável.

Nível 2: a criptografia, TLS

TLS (Transport Layer Security, sucessor do SSL) não substitui o TCP, ele se adiciona por cima. Concretamente, o TLS estabelece uma conexão TCP normal, depois negocia uma sessão criptografada em seu interior: troca de certificados, acordo sobre um algoritmo de criptografia, derivação de chaves de sessão. Tudo o que transita depois é criptografado e autenticado.

Três garantias distintas, frequentemente confundidas:

  • Confidencialidade: ninguém além das duas partes pode ler o conteúdo.

  • Integridade: qualquer alteração dos dados em trânsito é detectada.

  • Autenticação: mas no TLS clássico, unidirecional: o cliente verifica se o servidor é realmente quem ele diz ser (através de seu certificado, assinado por uma autoridade de confiança), mas o servidor não verifica nada sobre a identidade do cliente. É exatamente o modelo do HTTPS quando você visita um site: o navegador autentica o site, o site não autentica você (a autenticação do usuário passa por um mecanismo separado, cookie de sessão, token).

TLS 1.3 (a versão atual recomendada) reduziu o handshake a uma única ida e volta no caso comum, contra duas para TLS 1.2, o que reduz sensivelmente a latência de conexão.

Nível 2bis: mTLS -- a autenticação torna-se mútua

mTLS (mutual TLS) é TLS com uma restrição adicional: o servidor exige também um certificado do cliente, e o verifica. As duas partes provam sua identidade através de um certificado assinado por uma autoridade de confiança comum.

Esse é o mecanismo natural para a comunicação serviço-a-serviço em uma arquitetura distribuída: enquanto o HTTPS clássico basta para que um navegador fale com um servidor público, o mTLS responde a uma pergunta diferente: como um serviço interno sabe que está realmente falando com outro serviço interno autorizado, e não com um atacante que teria chegado à rede?

Cliente                                          Servidor
  │──── ClientHello ─────────────────────────────▶│
  │◀─── ServerHello + certificado do servidor ─────│
  │──── verifica o certificado do servidor ────────│
  │──── envia SEU PRÓPRIO certificado de cliente ─▶│
  │◀─── verifica o certificado do cliente ─────────│
  │──── chaves de sessão derivadas, canal cifrado ▶│

A contrapartida do mTLS é operacional: é necessária uma autoridade de certificação (CA) interna, um mecanismo de distribuição dos certificados para cada serviço, e uma estratégia de rotação/revogação. Em um ambiente de máquina única com poucos serviços, às vezes é mais complexidade do que benefício -- o mTLS se torna necessário a partir do momento em que o tráfego entre serviços atravessa uma rede que não controlamos completamente (vários hosts, cloud multi-tenant), ou assim que se deseja uma política do tipo zero trust, onde nenhum serviço é implicitamente digno de confiança simplesmente por estar "dentro" da rede.

Nível 3: os protocolos de aplicação sobre TCP+TLS

Uma vez o transporte e a criptografia em vigor, resta definir como estruturar as trocas. Esse é o papel dos protocolos de aplicação.

HTTP / HTTPS

HTTP é um protocolo requisição-resposta: o cliente abre uma conexão (ou reutiliza uma, com o keep-alive), envia uma requisição, aguarda uma resposta, a conexão pode então se fechar ou ser reutilizada. HTTPS é simplesmente HTTP sobre TLS -- o S não muda nada na semântica do protocolo, apenas no fato de que o transporte é criptografado.

O modelo requisição-resposta tem um limite estrutural: o servidor nunca pode falar primeiro. Ele só pode responder ao que o cliente pergunta. Para polling frequente (verificar "há novidades?" a cada segundo), funciona mas desperdiça recursos -- cada requisição recria uma sobrecarga protocolar para, na maioria das vezes, não ter nada de novo a anunciar.

WebSocket (WS / WSS)

WebSocket responde exatamente a esse limite. A conexão começa como uma requisição HTTP clássica (com um cabeçalho Upgrade: websocket), mas uma vez que o handshake é aceito, a conexão TCP subjacente não é mais um canal requisição-resposta HTTP -- ela se torna um canal bidirecional full-duplex onde cliente e servidor podem enviar mensagens a qualquer momento, sem ter que reemitir um ciclo requisição-resposta a cada troca.

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

WSS é simplesmente WebSocket sobre TLS, exatamente como HTTPS é HTTP sobre TLS. É o protocolo de escolha para tudo que necessita de push do servidor em tempo real -- chat, notificações, fluxo de trading, eventos de jogo -- sem querer gerenciar você mesmo um protocolo binário sobre TCP puro.

gRPC

Menos conhecido fora do mundo dos microsserviços mas central na comunicação serviço-a-serviço: o gRPC se apoia em HTTP/2 (portanto TCP + TLS opcional), serializa as mensagens em Protocol Buffers (binário, tipado, compacto -- ao contrário do JSON texto da maioria das APIs REST), e permite nativamente o streaming bidirecional graças ao multiplexação do HTTP/2 (vários fluxos lógicos em uma única conexão TCP, sem o head-of-line blocking que várias requisições HTTP/1.1 sequenciais teriam).

QUIC / HTTP3

QUIC muda o jogo ao partir do UDP em vez do TCP no nível do transporte, enquanto reimplementa por cima as garantias de confiabilidade que o TCP oferecia nativamente -- mas fluxo por fluxo em vez de globalmente, o que elimina o head-of-line blocking no nível do transporte (um pacote perdido em um fluxo não bloqueia mais os outros fluxos da mesma conexão). TLS 1.3 é integrado diretamente no QUIC em vez de adicionado por cima, o que reduz ainda mais a latência do handshake. HTTP/3 é HTTP sobre QUIC.

Visão geral: onde se situa cada protocolo

Camada Protocolos Papel Transporte TCP, UDP Fazer os bytes viajarem, confiável ou não Transporte (nova geração) QUIC UDP + confiabilidade por fluxo + TLS integrado Segurança TLS, mTLS Criptografia, integridade, autenticação (uni ou mútua) Aplicação HTTP/HTTPS, WS/WSS, gRPC Estruturar as trocas (requisição-resposta, bidirecional, RPC tipado)

Um exemplo concreto para fixar as ideias: uma arquitetura de microsserviços com um dashboard web e serviços internos poderia razoavelmente combinar HTTPS (dashboard ↔ API pública, autenticação unidirecional suficiente no lado do navegador), mTLS (serviço ↔ serviço internamente, autenticação mútua necessária), e WSS (notificações em tempo real empurradas para o dashboard) -- três protocolos de aplicação diferentes, todos construídos sobre a mesma base TCP + TLS.

Como escolher, na prática

Três perguntas geralmente bastam para decidir:

  1. Preciso de confiabilidade e ordem, ou a atualidade do dado é mais importante que sua entrega garantida? → TCP se sim, UDP se não (ou QUIC para ter ambos através de um compromisso diferente).

  2. O servidor precisa poder iniciar mensagens, ou o cliente faz sempre a primeira solicitação? → WebSocket/streaming gRPC se o servidor precisa empurrar, HTTP clássico caso contrário.

  3. As duas partes precisam provar mutuamente sua identidade, ou apenas uma das duas precisa ser verificada? → mTLS para serviço-a-serviço em ambiente zero-trust, TLS simples para cliente público clássico.

A complexidade operacional aumenta a cada camada adicionada: TCP puro não tem nenhuma infraestrutura para gerenciar, TLS exige certificados, mTLS exige uma CA e uma estratégia de rotação, gRPC exige uma definição de esquema Protobuf compartilhada. O bom reflexo é só aumentar a complexidade quando a camada inferior mostra um limite concreto, não por antecipação.

Bagaimana mesin saling bicara : tur dari TCP hingga mTLS

Kenapa TCP, UDP, TLS, mTLS, HTTP dan WebSocket bukan alternatif yang bersaing melainkan lapisan bertumpuk; tur hierarkis komunikasi mesin ke mesin, dari transport mentah hingga autentikasi mutual.

Masalahnya : terlalu banyak singkatan, tidak cukup hierarki

TCP, UDP, TLS, mTLS, WebSocket, HTTP, HTTPS, gRPC, QUIC; sebagian besar sumber yang membahasnya menyajikannya sebagai daftar datar opsi yang bisa dipertukarkan, "pilih sesuai kasus pemakaian". Kenyataannya mereka tidak berada di bidang yang sama : sebagian adalah protokol transport, sebagian lapisan keamanan yang membungkus transport, sebagian lagi protokol aplikatif yang bersandar pada dua yang pertama. Memahami hierarki berarti memahami kenapa kita tidak pernah "memilih" antara TCP dan TLS: kita memilih TCP, lalu memutuskan apakah menaruh TLS di atasnya.

Artikel ini membangun ulang hierarki itu lapis per lapis, dari transport mentah hingga autentikasi mutual, dengan untuk tiap tingkat : apa yang dijaminnya, apa yang tidak dijaminnya, dan kapan cukup berhenti di sana.

Tingkat 1 : transport (TCP lawan UDP)

Semuanya dimulai di sini. TCP dan UDP adalah dua protokol utama lapisan Transport (Layer 4) model OSI. Peran mereka identik : mengangkut aliran data antara dua aplikasi yang berjalan di mesin berbeda. Namun, cara mereka mencapainya sangat berbeda.

Penting dipahami bahwa IP (Internet Protocol), yang terletak di lapisan jaringan (Layer 3), hanya merutekan paket dari satu host ke host lain. Ia tidak menjamin tibanya, urutannya, bahkan keunikannya. Router hanya mengambil keputusan routing independen untuk tiap paket.

Tepat ketiadaan jaminan inilah yang dikompensasi TCP, sementara UDP sengaja memilih tidak menambah apa pun agar tetap sangat ringan.

TCP : keandalan di atas segalanya

TCP (Transmission Control Protocol) adalah protokol berorientasi koneksi (connection-oriented). Sebelum mempertukarkan satu oktet data pun, kedua mesin harus membangun koneksi logis.

Koneksi ini dibuat berkat Three-Way Handshake yang terkenal :

Client                           Serveur
SYN ---------------------------->
        <--------------------- SYN + ACK
ACK ---------------------------->
Connexion établie

Setiap tahap punya tujuan tepat :

  • SYN : klien mengumumkan ingin membuka koneksi dan memberikan nomor urut pertama (Initial Sequence Number - ISN).

  • SYN-ACK : server menerima koneksi, mengakui penerimaan SYN dan memberikan pada gilirannya nomor urutnya sendiri.

  • ACK : klien mengonfirmasi penerimaan informasi server.

Sejak momen itu, kedua mesin mengenal keadaan koneksi dan bisa mulai bertukar data.

Nomor urut

TCP tidak melihat data sebagai suksesi paket, melainkan sebagai aliran oktet kontinu (byte stream).

Setiap oktet yang dikirim punya nomor urut.

Contoh :

Pesan :

Bonjour

B = oktet 0
o = oktet 1
n = oktet 2
...

Kalau segmen berisi oktet 1000 hingga 1499 hilang selama transport, penerima bisa mendeteksi tepat apa yang kurang.

Pengirim mentransmisikan ulang hanya porsi itu.

Granularitas ini salah satu alasan ketangguhan TCP.

Acknowledgment (ACK)

Setelah menerima data, penerima mengirim ACK (Acknowledgment).

Berlawanan dengan yang sering dibayangkan, ACK bukan berarti :

"Saya menerima paket ini"

Ia lebih berarti :

"Saya menerima semua oktet hingga nomor X."

Misalnya :

Klien mengirim :

0 → 999

Server menjawab :

ACK = 1000

Ini berarti :

"Semua yang sebelum oktet 1000 tiba dengan baik."

Mekanisme ini memungkinkan mengakui penerimaan beberapa segmen sekaligus (cumulative acknowledgments), sehingga mengurangi jumlah paket kontrol.

Retransmisi

Kalau ACK tidak pernah tiba, TCP mengasumsikan segmen hilang.

Ia mentransmisikan ulang otomatis.

Penundaan retransmisi (Retransmission Timeout – RTO) tidak tetap.

TCP terus-menerus mengukur waktu pulang-pergi (RTT) berkat ACK yang diterima dan menghitung dinamis RTO agar menghindari retransmisi yang tidak perlu.

Implementasi modern juga memakai mekanisme seperti Fast Retransmit : ketika pengirim menerima beberapa ACK duplikat (umumnya tiga), ia menyimpulkan segmen antara telah hilang dan mengirimnya ulang segera, tanpa menunggu pewaktu kedaluwarsa.

Penataan ulang paket

Internet sama sekali tidak menjamin dua paket mengikuti jalur yang sama.

Contoh :

Paket 1
Paris
  ↓
Londres
  ↓
New York

Paket 2
Paris
  ↓
Francfort
  ↓
Chicago
  ↓
New York

Paket kedua bisa tiba sebelum yang pertama.

TCP lalu menyimpan sementara segmen yang diterima di luar urutan dalam buffer (reassembly buffer), lalu merakitnya ulang sebelum menyerahkannya ke aplikasi.

Bagi aplikasi, semuanya tampak tiba sempurna berurutan.

Kontrol aliran

Satu koneksi tidak hanya bergantung pada jaringan.

Penerima juga punya kapasitas memori terbatas.

Kalau ia menerima lebih cepat daripada bisa memproses data, buffernya akhirnya jenuh.

TCP menyelesaikan masalah ini berkat jendela geser (Sliding Window).

Penerima menunjukkan di setiap ACK :

Window = 32768 oktet

Ini berarti :

"Kamu bisa mengirimi saya hingga 32 Ko tambahan."

Kalau jendela ini jatuh ke nol :

Window = 0

Pengirim menangguhkan sementara transmisi hingga penerima mengumumkan jendela baru yang tersedia.

Mekanisme ini membentuk kontrol aliran (Flow Control) dan mencegah host cepat membanjiri host yang lebih lambat.

Kontrol kongesti

Meski penerima mampu menyerap data, jaringan itu sendiri bisa jenuh.

Router punya antrean (queues) terbatas.

Ketika meluap, paket dibuang.

TCP menafsirkan kehilangan sebagai tanda kongesti dan otomatis menyesuaikan lajunya berkat jendela kongesti (Congestion Window – cwnd).

Algoritma modern (seperti Reno, CUBIC atau BBR, tergantung sistem operasi) menyesuaikan jendela ini agar menemukan keseimbangan antara laju maks dan stabilitas jaringan.

Versi awal TCP terutama memakai dua mekanisme :

  • Slow Start : peningkatan eksponensial laju hingga mendeteksi kongesti.

  • Congestion Avoidance : pertumbuhan lalu lebih hati-hati, umumnya linear.

Adaptasi permanen ini salah satu alasan TCP tetap performan meski kualitas jaringan bervariasi.

Penutupan koneksi

Berlawanan dengan UDP, koneksi TCP juga punya penutupan bersih.

Setiap ujung menutup independen alirannya berkat bendera FIN.

Penutupan lengkap umumnya membutuhkan empat pertukaran :

FIN
ACK
FIN
ACK

Prosedur ini menjamin semua data dalam transit telah terkirim baik sebelum koneksi dihancurkan.

UDP : kesederhanaan maksimal

UDP (User Datagram Protocol) menganut filosofi kebalikannya.

Ia tanpa koneksi (connectionless).

Tidak ada :

  • handshake apa pun ;

  • nomor urut apa pun ;

  • acknowledgment apa pun ;

  • retransmisi apa pun ;

  • kontrol aliran apa pun ;

  • kontrol kongesti apa pun.

Setiap pesan hanya dienkapsulasi dalam datagram independen, ditransmisikan ke jaringan, lalu dilupakan pengirim.

Aplikasi → Datagram UDP → IP → Internet

Protokol tidak menyimpan keadaan apa pun antara dua pengiriman.

Setiap datagram sepenuhnya independen dari sebelumnya.

Integritas data

Meski UDP tidak menjamin pengiriman maupun urutan, ia tetap melindungi integritas data berkat checksum.

Saat penerimaan, checksum dihitung ulang.

  • Kalau nilainya cocok, datagram diterima.

  • Kalau tidak, ia langsung ditolak.

Jadi UDP mendeteksi data yang rusak, tapi tidak pernah mencoba memulihkannya.

Kenapa UDP begitu cepat?

Header UDP hanya berisi 8 oktet, lawan minimum 20 oktet untuk TCP (belum termasuk opsi seperti timestamp, SACK atau Window Scaling).

Karena tidak ada koneksi yang dipelihara, sistem operasi tidak harus melacak keadaan tiap pertukaran, yang juga mengurangi konsumsi memori dan biaya pemrosesan.

Aplikasi menerima data hampir begitu tiba, tanpa menunggu kemungkinan retransmisi.

Ketika kehilangan data lebih baik

Ide dasarnya sederhana :

Informasi lama bisa kurang berharga daripada informasi yang hilang.

Ambil percakapan VoIP.

Setiap paket membawa sekitar 20 ms suara.

Kalau satu paket hilang, mentransmisikannya ulang sering memakan waktu lebih lama dari 20 ms itu.

Ketika akhirnya tiba, percakapan sudah maju.

Sebagian besar aplikasi lebih memilih menutupi kehilangan (interpolasi, hening, koreksi error) daripada menunggu retransmisi.

Penalaran yang sama berlaku :

  • pada game multipemain waktu nyata ;

  • pada streaming video ;

  • pada aliran telemetri ;

  • pada sensor IoT ;

  • pada data posisi GPS.

Nilai terbaru hampir selalu lebih berguna daripada nilai lama yang sempurna andalnya.

Tingkat 2 : enkripsi, TLS

TLS (Transport Layer Security, penerus SSL) tidak menggantikan TCP, ia ditambahkan di atasnya. Konkretnya, TLS membangun koneksi TCP normal, lalu menegosiasikan sesi terenkripsi di dalamnya : pertukaran sertifikat, kesepakatan algoritma enkripsi, derivasi kunci sesi. Semua yang transit kemudian terenkripsi dan terautentikasi.

Tiga jaminan berbeda, sering tertukar :

  • Kerahasiaan : tidak ada selain kedua pihak yang bisa membaca isinya.

  • Integritas : setiap perubahan data dalam transit terdeteksi.

  • Autentikasi : tapi dalam TLS klasik, satu arah : klien memverifikasi bahwa server memang seperti yang diklaimnya (lewat sertifikatnya, yang ditandatangani otoritas tepercaya), tapi server tidak memverifikasi apa pun soal identitas klien. Tepat inilah model HTTPS ketika kamu mengunjungi situs : peramban mengautentikasi situs, situs tidak mengautentikasimu (autentikasi pengguna lewat mekanisme terpisah, cookie sesi, token).

TLS 1.3 (versi terkini yang direkomendasikan) telah mengurangi handshake menjadi satu pulang-pergi dalam kasus umum, lawan dua untuk TLS 1.2, yang mengurangi latensi koneksi secara terasa.

Tingkat 2bis : mTLS -- autentikasi menjadi mutual

mTLS (mutual TLS) adalah TLS dengan batasan tambahan : server menuntut juga sertifikat dari klien, dan memverifikasinya. Kedua pihak membuktikan identitasnya lewat sertifikat yang ditandatangani otoritas tepercaya bersama.

Ini mekanisme alami untuk komunikasi layanan-ke-layanan dalam arsitektur terdistribusi : di mana HTTPS klasik cukup supaya peramban bicara ke server publik, mTLS menjawab pertanyaan berbeda; bagaimana layanan internal tahu bahwa ia benar-benar bicara ke layanan internal lain yang diotorisasi, dan bukan ke penyerang yang mendarat di jaringan?

Klien                                          Server
  │──── ClientHello ─────────────────────────────▶│
  │◀─── ServerHello + sertifikat server ──────────│
  │──── memverifikasi sertifikat server ─────────────│
  │──── mengirim sertifikat klien MILIKNYA ──────▶│
  │◀─── memverifikasi sertifikat klien ───────────────│
  │──── kunci sesi diderivasi, kanal terenkripsi ──▶│

Imbalan mTLS bersifat operasional : perlu otoritas sertifikasi (CA) internal, mekanisme distribusi sertifikat ke tiap layanan, dan strategi rotasi/pencabutan. Dalam lingkungan satu mesin dengan sedikit layanan, ini kadang lebih banyak kerumitan daripada manfaat -- mTLS menjadi perlu sejak trafik antar-layanan melintasi jaringan yang tidak sepenuhnya kita kendalikan (banyak host, cloud multi-tenant), atau begitu kita menginginkan kebijakan tipe zero trust, di mana tidak ada layanan yang secara implisit layak dipercaya hanya karena ia "di dalam" jaringan.

Tingkat 3 : protokol aplikatif di atas TCP+TLS

Begitu transport dan enkripsi terpasang, tinggal mendefinisikan bagaimana menstruktur pertukaran. Itulah peran protokol aplikatif.

HTTP / HTTPS

HTTP adalah protokol permintaan-respons : klien membuka koneksi (atau memakai ulang, dengan keep-alive), mengirim permintaan, menunggu respons, koneksi lalu bisa ditutup atau dipakai ulang. HTTPS hanyalah HTTP di atas TLS -- S tidak mengubah apa pun pada semantik protokol, hanya pada fakta bahwa transport terenkripsi.

Model permintaan-respons punya batas struktural : server tidak pernah bisa bicara duluan. Ia hanya bisa menjawab apa yang diminta klien. Untuk polling sering ("ada yang baru?" setiap detik), itu bisa tapi membuang sumber daya -- setiap permintaan menciptakan ulang overhead protokoler untuk, sebagian besar waktu, tidak mengumumkan hal baru apa pun.

WebSocket (WS / WSS)

WebSocket menjawab tepat batas ini. Koneksi dimulai sebagai permintaan HTTP klasik (dengan header Upgrade: websocket), tapi begitu jabat tangan diterima, koneksi TCP di bawahnya bukan lagi kanal permintaan-respons HTTP -- ia menjadi kanal dua arah full-duplex di mana klien dan server bisa mengirim pesan kapan pun, tanpa harus menerbitkan ulang siklus permintaan-respons di setiap pertukaran.

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

WSS hanyalah WebSocket di atas TLS, persis seperti HTTPS adalah HTTP di atas TLS. Ini protokol pilihan untuk semua yang membutuhkan push server waktu nyata -- chat, notifikasi, aliran trading, event permainan -- tanpa ingin mengelola sendiri protokol biner di atas TCP telanjang.

gRPC

Kurang dikenal di luar dunia microservice tapi sentral dalam komunikasi layanan-ke-layanan : gRPC bersandar pada HTTP/2 (jadi TCP + TLS opsional), menyerilakan pesan dalam Protocol Buffers (biner, bertipe, ringkas - berlawanan dengan JSON teks dari sebagian besar API REST), dan memungkinkan native streaming dua arah berkat multiplexing HTTP/2 (banyak aliran logis pada satu koneksi TCP, tanpa head-of-line blocking yang dimiliki banyak permintaan HTTP/1.1 sekuensial).

QUIC / HTTP3

QUIC mengubah keadaan dengan berangkat dari UDP alih-alih TCP di tingkat transport, sambil mengimplementasikan ulang di atasnya jaminan keandalan yang ditawarkan TCP secara native - tapi per aliran alih-alih global, yang menghilangkan head-of-line blocking di tingkat transport (paket hilang pada satu aliran tidak lagi memblokir aliran lain dari koneksi yang sama). TLS 1.3 terintegrasi langsung dalam QUIC alih-alih ditambahkan di atasnya, yang makin mengurangi latensi handshake. HTTP/3 adalah HTTP di atas QUIC.

Gambaran umum : di mana posisi tiap protokol

Lapisan Protokol Peran Transport TCP, UDP Membuat oktet berpergian, andal atau tidak Transport (generasi baru) QUIC UDP + keandalan per aliran + TLS terintegrasi Keamanan TLS, mTLS Enkripsi, integritas, autentikasi (satu arah atau mutual) Aplikasi HTTP/HTTPS, WS/WSS, gRPC Menstruktur pertukaran (permintaan-respons, dua arah, RPC bertipe)

Contoh konkret untuk memantapkan ide : arsitektur microservice dengan dashboard web dan layanan internal bisa secara wajar menggabungkan HTTPS (dashboard ↔ API publik, autentikasi satu arah cukup di sisi peramban), mTLS (layanan ↔ layanan secara internal, autentikasi mutual diperlukan), dan WSS (notifikasi waktu nyata didorong ke dashboard) -- tiga protokol aplikatif berbeda, semuanya dibangun di atas fondasi yang sama TCP + TLS.

Cara memilih, dalam praktik

Tiga pertanyaan umumnya cukup untuk memutuskan :

  1. Apakah saya butuh keandalan dan urutan, atau kesegaran data lebih utama daripada pengiriman terjamin? → TCP kalau ya, UDP kalau tidak (atau QUIC untuk mendapatkan keduanya sekaligus lewat kompromi berbeda).

  2. Haruskah server bisa memulai pesan, atau klien selalu yang meminta duluan? → WebSocket/streaming gRPC kalau server harus mendorong, HTTP klasik kalau tidak.

  3. Haruskah kedua pihak saling membuktikan identitas, atau hanya satu yang perlu diverifikasi? → mTLS untuk layanan-ke-layanan di lingkungan zero-trust, TLS sederhana untuk klien publik klasik.

Kompleksitas operasional meningkat di setiap lapisan yang ditambahkan, TCP telanjang tidak punya infrastruktur yang dikelola, TLS membutuhkan sertifikat, mTLS membutuhkan CA dan strategi rotasi, gRPC membutuhkan definisi skema Protobuf bersama. Refleks yang benar adalah naik kompleksitas hanya ketika lapisan di bawahnya menunjukkan batas konkret, bukan karena antisipasi.

मशीनें कैसे बात करती हैं : TCP से mTLS तक दौरा

TCP, UDP, TLS, mTLS, HTTP और WebSocket प्रतिस्पर्धी विकल्प क्यों नहीं बल्कि परत दर परत ढेर हैं; कच्चे परिवहन से पारस्परिक प्रमाणीकरण तक मशीन से मशीन संचार का पदानुक्रमित दौरा।

समस्या : बहुत सारे संक्षिप्त, पदानुक्रम कम

TCP, UDP, TLS, mTLS, WebSocket, HTTP, HTTPS, gRPC, QUIC; ज्यादातर संसाधन जो इनकी बात करते हैं उन्हें विनिमेय विकल्पों की सपाट सूची के रूप में पेश करते हैं, "उपयोग मामले के अनुसार चुनने को"। वास्तव में वे एक ही तल पर नहीं हैं : कुछ परिवहन प्रोटोकॉल हैं, दूसरे सुरक्षा परतें हैं जो परिवहन के चारों ओर लिपटती हैं, और अन्य applicative प्रोटोकॉल हैं जो पहले दोनों पर निर्भर हैं। पदानुक्रम समझना यह समझना है कि हम TCP और TLS के बीच कभी "चुनते" नहीं: हम TCP चुनते हैं, फिर तय करते हैं कि ऊपर TLS रखना है या नहीं।

यह लेख इस पदानुक्रम को परत दर परत फिर से बनाता है, कच्चे परिवहन से पारस्परिक प्रमाणीकरण तक, हर स्तर के लिए : वह क्या गारंटी देता है, वह क्या गारंटी नहीं देता, और कब उसी से संतोष करना है।

स्तर 1 : परिवहन (TCP बनाम UDP)

सब यहाँ शुरू होता है। TCP और UDP OSI मॉडल की परिवहन (Layer 4) परत के दो मुख्य प्रोटोकॉल हैं। उनकी भूमिका समान है : अलग मशीनों पर चल रहे दो application के बीच डेटा प्रवाह पहुँचाना। फिर भी, वहाँ पहुँचने का उनका तरीका मौलिक रूप से अलग है।

यह समझना महत्वपूर्ण है कि IP (Internet Protocol), नेटवर्क परत (Layer 3) पर स्थित, सिर्फ एक host से दूसरे तक पैकेट पहुँचाता है। वह न उनकी पहुँच गारंटी देता है, न उनका क्रम, न उनकी अद्वितीयता भी। router हर पैकेट के लिए स्वतंत्र routing निर्णय लेते हैं।

ठीक गारंटियों की यही अनुपस्थिति है जिसकी भरपाई TCP करता है, जबकि UDP जानबूझकर अत्यंत हल्का रहने के लिए कुछ नहीं जोड़ना चुनता है।

TCP : विश्वसनीयता पहले

TCP (Transmission Control Protocol) एक कनेक्शन उन्मुख (connection-oriented) प्रोटोकॉल है। डेटा का एक भी octet आदान प्रदान करने से पहले, दोनों मशीनों को तार्किक कनेक्शन स्थापित करना होगा।

यह कनेक्शन प्रसिद्ध Three-Way Handshake से बनता है :


Client                           Serveur
SYN ---------------------------->
        <--------------------- SYN + ACK
ACK ---------------------------->
Connexion établie

हर चरण का सटीक उद्देश्य है :

  • SYN : client घोषणा करता है कि वह कनेक्शन खोलना चाहता है और पहला अनुक्रम संख्या (Initial Sequence Number - ISN) देता है।

  • SYN-ACK : serveur कनेक्शन स्वीकार करता है, SYN की प्राप्ति स्वीकार करता है और अपनी ओर से अपना अनुक्रम संख्या देता है।

  • ACK : client serveur की जानकारी की प्राप्ति पुष्टि करता है।

इस क्षण से, दोनों मशीनें कनेक्शन स्थिति जानती हैं और डेटा आदान प्रदान शुरू कर सकती हैं।

अनुक्रम संख्याएँ

TCP डेटा को पैकेटों के क्रम के रूप में नहीं देखता, बल्कि octet की सतत धारा (byte stream) के रूप में देखता है।

भेजे गए हर octet की अनुक्रम संख्या होती है।

उदाहरण :

संदेश :

Bonjour

B = octet 0
o = octet 1
n = octet 2
...

अगर परिवहन के दौरान octet 1000 से 1499 वाला खंड खो जाता है, तो प्राप्तकर्ता बिल्कुल पहचान सकता है कि क्या छूटा है।

प्रेषक सिर्फ वही हिस्सा फिर से भेजता है।

यह दानेदारी TCP की मजबूती के कारणों में से एक है।

प्राप्ति स्वीकृतियाँ (ACK)

डेटा प्राप्ति के बाद, गंतव्य ACK (Acknowledgment) भेजता है।

अक्सर कल्पना के विपरीत, ACK का मतलब नहीं है :

"मुझे यह पैकेट मिला"

उसका मतलब बल्कि है :

"मुझे संख्या X तक सभी octet मिले।"

उदाहरण के लिए :

Client भेजता है :

0 → 999

Serveur जवाब देता है :

ACK = 1000

इसका मतलब है :

"octet 1000 से पहले सब कुछ अच्छी तरह पहुँचा।"

यह तंत्र एक साथ कई खंडों की प्राप्ति स्वीकार करने देता है (cumulative acknowledgments), इस तरह नियंत्रण पैकेट संख्या घटाता है।

पुनः प्रसारण

अगर ACK कभी नहीं आता, तो TCP मानता है कि खंड खो गया है।

वह उसे अपने आप फिर से भेजता है।

पुनः प्रसारण विलंब (Retransmission Timeout – RTO) स्थिर नहीं है।

TCP प्राप्त ACK से round trip समय (RTT) लगातार मापता है और अनावश्यक पुनः प्रसारण से बचने के लिए RTO गतिशील गणना करता है।

आधुनिक कार्यान्वयन Fast Retransmit जैसे तंत्र भी इस्तेमाल करते हैं : जब प्रेषक कई दोहराए ACK पाता है (आमतौर पर तीन), तो वह निष्कर्ष निकालता है कि बीच का खंड खो गया है और उसे timer समाप्ति प्रतीक्षा किए बिना तुरंत फिर से भेजता है।

पैकेट पुनर्व्यवस्था

Internet बिल्कुल गारंटी नहीं देता कि दो पैकेट एक ही रास्ते चलेंगे।

उदाहरण :

Paquet 1
Paris
  ↓
Londres
  ↓
New York

Paquet 2
Paris
  ↓
Francfort
  ↓
Chicago
  ↓
New York

दूसरा पैकेट पहले से पहले पहुँच सकता है।

TCP तब प्राप्त खंडों को अस्थायी रूप से क्रम से बाहर बफर (reassembly buffer) में संग्रहित करता है, फिर application को देने से पहले उन्हें फिर से जोड़ता है।

application के लिए, सब कुछ पूरी तरह क्रम में आता लगता है।

प्रवाह नियंत्रण

कनेक्शन सिर्फ नेटवर्क पर निर्भर नहीं करता।

प्राप्तकर्ता की स्मृति क्षमता भी सीमित होती है।

अगर वह जितना प्रोसेस कर सकता है उससे तेज प्राप्त करता है, तो उसके buffer आखिर संतृप्त हो जाते हैं।

TCP इस समस्या को चल विंडो (Sliding Window) से सुलझाता है।

प्राप्तकर्ता हर ACK में बताता है :

Window = 32768 octets

इसका मतलब है :

"तुम मुझे 32 Ko अतिरिक्त तक भेज सकते हो।"

अगर यह विंडो शून्य पर गिरती है :

Window = 0

प्रेषक अस्थायी रूप से प्रसारण निलंबित करता है जब तक प्राप्तकर्ता नई उपलब्ध विंडो घोषित न करे।

यह तंत्र प्रवाह नियंत्रण (Flow Control) बनाता है और रोकता है कि तेज host धीमे host को डुबो दे।

भीड़ नियंत्रण

भले ही प्राप्तकर्ता डेटा अवशोषित करने में सक्षम हो, नेटवर्क खुद संतृप्त हो सकता है।

router के पास सीमित कतारें (queues) होती हैं।

जब वे छलकती हैं, पैकेट हटाए जाते हैं।

TCP हानियों को भीड़ संकेत मानता है और भीड़ विंडो (Congestion Window – cwnd) से अपनी दर अपने आप अनुकूलित करता है।

आधुनिक एल्गोरिदम (जैसे Reno, CUBIC या BBR, operating system अनुसार) अधिकतम दर और नेटवर्क स्थिरता के बीच संतुलन खोजने के लिए इस विंडो समायोजित करते हैं।

TCP के पहले संस्करण मुख्यतः दो तंत्र इस्तेमाल करते थे :

  • Slow Start : भीड़ पहचानने तक दर की घातांकीय वृद्धि।

  • Congestion Avoidance : फिर ज्यादा सतर्क वृद्धि, आमतौर पर रैखिक।

यह स्थायी अनुकूलन कारणों में से एक है जिनसे TCP नेटवर्क गुणवत्ता भिन्नता के बावजूद प्रदर्शनकारी रहता है।

कनेक्शन बंद करना

UDP के विपरीत, TCP कनेक्शन की साफ बंदी भी होती है।

हर छोर FIN ध्वज से अपना प्रवाह स्वतंत्र बंद करता है।

पूरी बंदी के लिए आमतौर पर चार आदान प्रदान चाहिए :

FIN
ACK
FIN
ACK

यह प्रक्रिया गारंटी देती है कि पारगमन में सारा डेटा कनेक्शन नष्ट करने से पहले अच्छी तरह पहुँचाया गया है।

UDP : अधिकतम सरलता

UDP (User Datagram Protocol) उल्टी दर्शन अपनाता है।

यह कनेक्शन रहित (connectionless) है।

मौजूद नहीं है :

  • कोई handshake ;

  • कोई अनुक्रम संख्या ;

  • कोई प्राप्ति स्वीकृति ;

  • कोई पुनः प्रसारण ;

  • कोई प्रवाह नियंत्रण ;

  • कोई भीड़ नियंत्रण।

हर संदेश बस स्वतंत्र datagram में लपेटा जाता है, नेटवर्क को प्रेषित किया जाता है, फिर प्रेषक भूल जाता है।

Application → Datagramme UDP → IP → Internet

प्रोटोकॉल दो भेजने के बीच कोई स्थिति नहीं रखता।

हर datagram पिछले से पूरी तरह स्वतंत्र है।

डेटा अखंडता

हालाँकि UDP न वितरण न क्रम गारंटी देता है, वह checksum से डेटा अखंडता फिर भी सुरक्षित करता है।

प्राप्ति पर, checksum फिर से गणना किया जाता है।

  • अगर मान मेल खाते हैं, तो datagram स्वीकार किया जाता है।

  • वरना, वह तुरंत अस्वीकृत होता है।

UDP इसलिए भ्रष्ट डेटा पहचानता है, लेकिन उन्हें कभी पुनः प्राप्त करने की कोशिश नहीं करता।

UDP इतना तेज क्यों है ?

UDP हेडर में सिर्फ 8 octet होते हैं, TCP के लिए न्यूनतम 20 octet के मुकाबले (timestamp, SACK या Window Scaling जैसे विकल्प गिने बिना)।

कोई कनेक्शन बनाए न रखने से, operating system को हर आदान प्रदान की स्थिति नहीं देखनी पड़ती, जो स्मृति खपत और प्रोसेसिंग लागत भी घटाता है।

application डेटा लगभग पहुँचते ही पाता है, संभावित पुनः प्रसारण प्रतीक्षा किए बिना।

जब डेटा खोना बेहतर हो

मूलभूत विचार सरल है :

पुरानी जानकारी खोई जानकारी से कम मूल्यवान हो सकती है।

VoIP बातचीत लो।

हर पैकेट लगभग 20 ms आवाज ले जाता है।

अगर कोई पैकेट खो जाता है, तो उसे फिर से भेजने में अक्सर इन 20 ms से ज्यादा समय लगेगा।

जब वह आखिर पहुँचेगा, बातचीत पहले ही आगे बढ़ चुकी होगी।

ज्यादातर application तब हानि छिपाना पसंद करते हैं (अंतर्वेशन, मौन, त्रुटि सुधार) बजाय पुनः प्रसारण प्रतीक्षा के।

वही तर्क लागू होता है :

  • वास्तविक समय मल्टीप्लेयर गेम ;

  • वीडियो streaming ;

  • telemetry प्रवाह ;

  • IoT सेंसर ;

  • GPS स्थिति डेटा।

हाल मान लगभग हमेशा पूरी तरह विश्वसनीय पुराने मान से ज्यादा उपयोगी होता है।

स्तर 2 : एन्क्रिप्शन, TLS

TLS (Transport Layer Security, SSL का उत्तराधिकारी) TCP को बदलता नहीं, वह उसके ऊपर जुड़ता है। ठोस रूप में, TLS सामान्य TCP कनेक्शन स्थापित करता है, फिर अंदर एन्क्रिप्टेड सत्र बातचीत करता है : प्रमाणपत्र आदान प्रदान, एन्क्रिप्शन एल्गोरिदम पर सहमति, सत्र कुंजी व्युत्पत्ति। फिर जो कुछ गुजरता है वह एन्क्रिप्ट और प्रमाणित होता है।

तीन अलग गारंटियाँ, अक्सर भ्रमित :

  • गोपनीयता : दोनों पक्षों के अलावा कोई और सामग्री नहीं पढ़ सकता।

  • अखंडता : पारगमन में डेटा का कोई बदलाव पहचाना जाता है।

  • प्रमाणीकरण : लेकिन क्लासिक TLS में, एकतरफा : client जाँचता है कि serveur वही है जो वह होने का दावा करता है (उसके प्रमाणपत्र से, विश्वास प्राधिकारी द्वारा हस्ताक्षरित), लेकिन serveur client की पहचान पर कुछ नहीं जाँचता। ठीक HTTPS मॉडल है जब तुम कोई साइट देखते हो : ब्राउजर साइट प्रमाणित करता है, साइट तुम्हें प्रमाणित नहीं करती (उपयोगकर्ता प्रमाणीकरण अलग तंत्र से गुजरता है, सत्र cookie, token)।

TLS 1.3 (वर्तमान अनुशंसित संस्करण) ने handshake को सामान्य मामले में एक ही round trip घटाया है, TLS 1.2 के दो के मुकाबले, जो कनेक्शन विलंबता संवेदनशील घटाता है।

स्तर 2bis : mTLS, प्रमाणीकरण पारस्परिक होता है

mTLS (mutual TLS) अतिरिक्त बाधा वाला TLS है : serveur भी client से प्रमाणपत्र माँगता है, और उसे जाँचता है। दोनों पक्ष सामान्य विश्वास प्राधिकारी द्वारा हस्ताक्षरित प्रमाणपत्र से अपनी पहचान साबित करते हैं।

यह वितरित आर्किटेक्चर में service से service संचार का प्राकृतिक तंत्र है : जहाँ क्लासिक HTTPS ब्राउजर को सार्वजनिक serveur से बात करने के लिए काफी है, mTLS अलग प्रश्न का उत्तर देता है; आंतरिक service कैसे जानती है कि वह सच में दूसरी अधिकृत आंतरिक service से बात कर रही है, न कि हमलावर से जो नेटवर्क पर उतर आया है ?

Client                                          Serveur
  │──── ClientHello ─────────────────────────────▶│
  │◀─── ServerHello + certificat serveur ──────────│
  │──── vérifie le certificat serveur ─────────────│
  │──── envoie SON PROPRE certificat client ──────▶│
  │◀─── vérifie le certificat client ───────────────│
  │──── clés de session dérivées, canal chiffré ──▶│

mTLS की भरपाई परिचालनात्मक है : आंतरिक प्रमाणन प्राधिकारी (CA) चाहिए, हर service को प्रमाणपत्र वितरण तंत्र, और घूर्णन/निरसन रणनीति। कम service वाले एकल मशीन वातावरण में, यह कभी कभी लाभ से ज्यादा जटिलता है, mTLS उस क्षण से जरूरी होता है जब अंतर service ट्रैफिक ऐसे नेटवर्क से गुजरता है जिसे हम पूरी तरह नियंत्रित नहीं करते (कई host, multi-tenant cloud), या जैसे ही zero trust तरह की नीति चाहिए, जहाँ कोई service सिर्फ इसलिए निहित विश्वसनीय नहीं है क्योंकि वह नेटवर्क के "अंदर" है।

स्तर 3 : TCP+TLS के ऊपर applicative प्रोटोकॉल

एक बार परिवहन और एन्क्रिप्शन जगह पर, आदान प्रदान कैसे संरचित करें परिभाषित करना बाकी है। यह applicative प्रोटोकॉल की भूमिका है।

HTTP / HTTPS

HTTP अनुरोध उत्तर प्रोटोकॉल है : client कनेक्शन खोलता है (या keep-alive से फिर से इस्तेमाल करता है), अनुरोध भेजता है, उत्तर प्रतीक्षा करता है, कनेक्शन फिर बंद हो सकता है या फिर से इस्तेमाल हो सकता है। HTTPS, बस TLS पर HTTP है, S प्रोटोकॉल अर्थ नहीं बदलता, सिर्फ यह कि परिवहन एन्क्रिप्ट है।

अनुरोध उत्तर मॉडल की संरचनात्मक सीमा है : serveur कभी पहले नहीं बोल सकता। वह सिर्फ वही जवाब दे सकता है जो client माँगता है। बार बार polling के लिए ("क्या कुछ नया है ?" हर सेकंड जाँचना), यह चलता है लेकिन संसाधन बर्बाद करता है, हर अनुरोध प्रोटोकॉल overhead फिर से बनाता है, ज्यादातर समय घोषित करने को कुछ नया नहीं होता।

WebSocket (WS / WSS)

WebSocket ठीक इस सीमा का उत्तर देता है। कनेक्शन क्लासिक HTTP अनुरोध की तरह शुरू होता है (Upgrade: websocket हेडर के साथ), लेकिन एक बार handshake स्वीकार होने पर, अंतर्निहित TCP कनेक्शन HTTP अनुरोध उत्तर चैनल नहीं रहता, वह द्विदिश full-duplex चैनल बन जाता है जहाँ client और serveur किसी भी समय संदेश भेज सकते हैं, बिना हर आदान प्रदान पर अनुरोध उत्तर चक्र फिर से जारी किए।

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

WSS बस TLS पर WebSocket है, बिल्कुल जैसे HTTPS TLS पर HTTP है। यह हर चीज के लिए पसंदीदा प्रोटोकॉल है जिसे वास्तविक समय serveur push चाहिए, चैट, सूचनाएँ, trading प्रवाह, गेम घटनाएँ, बिना नंगे TCP पर खुद बाइनरी प्रोटोकॉल प्रबंधित करना चाहे।

gRPC

microservices दुनिया के बाहर कम ज्ञात लेकिन service से service संचार में केंद्रीय : gRPC HTTP/2 पर निर्भर है (इसलिए TCP + वैकल्पिक TLS), संदेश Protocol Buffers में क्रमबद्ध करता है (बाइनरी, typed, संक्षिप्त, ज्यादातर REST API के पाठ JSON के विपरीत), और HTTP/2 multiplexing से स्वाभाविक द्विदिश streaming देता है (एक ही TCP कनेक्शन पर कई तार्किक प्रवाह, बिना head-of-line blocking जो कई क्रमिक HTTP/1.1 अनुरोधों में होता)।

QUIC / HTTP3

QUIC परिवहन स्तर पर TCP के बजाय UDP से फिर से शुरू करके खेल बदलता है, फिर ऊपर विश्वसनीयता गारंटियाँ फिर से लागू करता है जो TCP स्वाभाविक देता था, लेकिन वैश्विक के बजाय प्रवाह दर प्रवाह, जो परिवहन स्तर पर head-of-line blocking खत्म करता है (एक प्रवाह पर खोया पैकेट उसी कनेक्शन के अन्य प्रवाहों को नहीं रोकता)। TLS 1.3 ऊपर जोड़े जाने के बजाय सीधे QUIC में एकीकृत है, जो handshake विलंबता और घटाता है। HTTP/3 QUIC पर HTTP है।

अवलोकन : हर प्रोटोकॉल कहाँ स्थित है

परत प्रोटोकॉल भूमिका परिवहन TCP, UDP octet पहुँचाना, विश्वसनीय या नहीं परिवहन (नई पीढ़ी) QUIC UDP + प्रवाह दर विश्वसनीयता + एकीकृत TLS सुरक्षा TLS, mTLS एन्क्रिप्शन, अखंडता, प्रमाणीकरण (एकल या पारस्परिक) Application HTTP/HTTPS, WS/WSS, gRPC आदान प्रदान संरचित करना (अनुरोध उत्तर, द्विदिश, typed RPC)

ठोस उदाहरण विचार स्थिर करने के लिए : web dashboard और आंतरिक service वाली microservices आर्किटेक्चर युक्तिसंगत HTTPS (dashboard ↔ सार्वजनिक API, ब्राउजर तरफ एकतरफा प्रमाणीकरण काफी), mTLS (service ↔ service आंतरिक, पारस्परिक प्रमाणीकरण जरूरी), और WSS (dashboard की ओर धकेली वास्तविक समय सूचनाएँ) जोड़ सकती है, तीन अलग applicative प्रोटोकॉल, सभी उसी TCP + TLS आधार पर बने।

व्यवहार में कैसे चुनें

आमतौर पर निर्णय के लिए तीन प्रश्न काफी हैं :

  1. क्या मुझे विश्वसनीयता और क्रम चाहिए, या डेटा ताजगी गारंटीकृत वितरण पर प्रधान है ? → हाँ होने पर TCP, नहीं होने पर UDP (या अलग समझौते से दोनों एक साथ पाने के लिए QUIC)।

  2. क्या serveur को संदेश शुरू करने में सक्षम होना चाहिए, या client हमेशा पहली माँग करता है ? → serveur को धकेलना हो तो WebSocket/gRPC streaming, वरना क्लासिक HTTP।

  3. क्या दोनों पक्षों को एक दूसरे को अपनी पहचान साबित करनी चाहिए, या सिर्फ एक को सत्यापित होना है ? → zero-trust वातावरण में service से service के लिए mTLS, क्लासिक सार्वजनिक client के लिए साधारण TLS।

जोड़ी हर परत पर परिचालन जटिलता बढ़ती है, नंगे TCP का प्रबंधित करने को कोई बुनियादी ढाँचा नहीं, TLS प्रमाणपत्र माँगता है, mTLS CA और घूर्णन रणनीति माँगता है, gRPC साझा Protobuf schema परिभाषा माँगता है। सही प्रवृत्ति तभी जटिलता बढ़ाना है जब नीचे की परत ठोस सीमा दिखाए, पूर्वानुमान से नहीं।

كيف تتكلم الآلات بينها : جولة من TCP إلى mTLS

لماذا TCP وUDP وTLS وmTLS وHTTP وWebSocket ليست بدائل متنافسة بل طبقات مكدسة ؛ جولة هرمية في التواصل آلة لآلة، من النقل الخام إلى المصادقة المتبادلة.

المشكلة : اختصارات كثيرة، وهرمية قليلة

TCP وUDP وTLS وmTLS وWebSocket وHTTP وHTTPS وgRPC وQUIC ؛ معظم الموارد التي تتكلم عنها تعرضها كقائمة مسطحة من الخيارات القابلة للتبديل، "تُختار حسب حالة الاستخدام". في الواقع ليست على نفس المستوى : بعضها بروتوكولات نقل، وبعضها طبقات أمان تلتف حول النقل، وبعضها الآخر بروتوكولات تطبيقية تستند إلى الأولين. فهم الهرمية يعني فهم لماذا لا "نختار" أبدا بين TCP وTLS : نختار TCP، ثم نقرر إن وضعنا TLS فوقه.

يعيد هذا المقال بناء هذه الهرمية طبقة بطبقة، من النقل الخام حتى المصادقة المتبادلة، مع ذكر ما يضمنه كل مستوى وما لا يضمنه ومتى نكتفي به.

المستوى 1 : النقل (TCP ضد UDP)

كل شيء يبدأ هنا. TCP وUDP هما البروتوكولان الرئيسيان لطبقة النقل (Layer 4) في نموذج OSI. دورهما متطابق : نقل تدفق بيانات بين تطبيقين يعملان على آلتين مختلفتين. لكن طريقتهما في ذلك مختلفة جذريا.

من المهم فهم أن IP (Internet Protocol)، الواقع في طبقة الشبكة (Layer 3)، لا يفعل إلا توجيه الحزم من مضيف إلى آخر. لا يضمن وصولها، ولا ترتيبها، ولا حتى فرادتها. فالموجهات تتخذ ببساطة قرارات توجيه مستقلة لكل حزمة.

وهذا الغياب الدقيق للضمانات هو ما يعوّضه TCP، بينما يختار UDP عمدا ألا يضيف شيئا ليبقى خفيفا للغاية.

TCP : الموثوقية أولا

TCP (Transmission Control Protocol) بروتوكول موجه بالاتصال (connection-oriented). قبل تبادل أي بايت من البيانات، يجب على الآلتين إقامة اتصال منطقي.

يُنشأ هذا الاتصال بفضل الـThree-Way Handshake الشهير :


Client                           Serveur
SYN ---------------------------->
        <--------------------- SYN + ACK
ACK ----------------------------> 
Connexion établie

كل خطوة لها هدف دقيق :

  • SYN : العميل يعلن أنه يريد فتح اتصال ويقدم أول رقم تسلسل (Initial Sequence Number - ISN).

  • SYN-ACK : الخادم يقبل الاتصال، ويقر استلام الـSYN ويقدم بدوره رقم تسلسله الخاص.

  • ACK : العميل يؤكد استلام معلومات الخادم.

من تلك اللحظة، تعرف الآلتان حالة الاتصال ويمكنهما بدء تبادل البيانات.

أرقام التسلسل

لا يرى TCP البيانات كتعاقب حزم، بل كـتدفق مستمر من البايتات (byte stream).

كل بايت مرسل يملك رقم تسلسل.

مثال :

Message :

Bonjour

B = octet 0
o = octet 1
n = octet 2
...

إذا ضاع مقطع يحوي البايتات 1000 إلى 1499 أثناء النقل، يستطيع المستقبل كشف ما ينقص بالضبط.

ويعيد المرسل إرسال ذلك الجزء فقط.

هذه الدقة من أسباب متانة TCP.

إشعارات الاستلام (ACK)

بعد استلام البيانات، يرسل المتلقي ACK (Acknowledgment).

وخلافا لما يُتصور غالبا، لا يعني ACK :

"لقد استلمت هذه الحزمة"

بل يعني :

"لقد استلمت كل البايتات حتى الرقم X."

مثلا :

Client envoie :

0 → 999

Serveur répond :

ACK = 1000

وهذا يعني :

"كل ما قبل البايت 1000 وصل جيدا."

تسمح هذه الآلية بالإقرار باستلام عدة مقاطع دفعة واحدة (cumulative acknowledgments)، مما يقلل عدد حزم التحكم.

إعادات الإرسال

إذا لم يصل ACK أبدا، يفترض TCP أن المقطع ضاع.

فيعيد إرساله تلقائيا.

مهلة إعادة الإرسال (Retransmission Timeout – RTO) ليست ثابتة.

يقيس TCP باستمرار زمن الذهاب والإياب (RTT) بفضل الـACK المستلمة ويحسب RTO ديناميكيا لتجنب إعادات إرسال غير ضرورية.

تستخدم التنفيذات الحديثة أيضا آليات مثل Fast Retransmit : عندما يتلقى المرسل عدة ACK مكررة (عادة ثلاثة)، يستنتج أن مقطعا وسيطا ضاع ويعيده فورا، دون انتظار انتهاء المؤقت.

إعادة ترتيب الحزم

لا يضمن الإنترنت إطلاقا أن تسلك حزمتان الطريق نفسه.

مثال :

Paquet 1
Paris
  ↓
Londres
  ↓
New York

Paquet 2
Paris
  ↓
Francfort
  ↓
Chicago
  ↓
New York

قد تصل الحزمة الثانية قبل الأولى.

يخزن TCP حينها مؤقتا المقاطع المستلمة خارج الترتيب في عازل (reassembly buffer)، ثم يعيد تجميعها قبل تسليمها للتطبيق.

وبالنسبة للتطبيق، يبدو كل شيء وكأنه يصل مرتبا تماما.

التحكم في التدفق

لا يعتمد الاتصال على الشبكة فقط.

فالمستقبل يملك أيضا قدرة ذاكرة محدودة.

وإذا استلم أسرع مما يستطيع معالجة البيانات، تشبع مخازنه المؤقتة في النهاية.

يحل TCP هذه المشكلة بفضل نافذة منزلقة (Sliding Window).

يعلن المستقبل في كل ACK :

Window = 32768 octets

وهذا يعني :

"يمكنك إرسال حتى 32 Ko إضافية."

وإذا سقطت هذه النافذة إلى الصفر :

Window = 0

يعلق المرسل مؤقتا الإرسالات حتى يعلن المستقبل نافذة جديدة متاحة.

تشكل هذه الآلية التحكم في التدفق (Flow Control) وتمنع مضيفا سريعا من إغراق مضيف أبطأ.

التحكم في الازدحام

حتى لو كان المستقبل قادرا على امتصاص البيانات، قد تصبح الشبكة نفسها مشبعة.

تملك الموجهات طوابير انتظار (queues) محدودة.

وعندما تفيض، تُحذف الحزم.

يفسر TCP الفقدان كعلامة ازدحام ويكيّف معدل إرساله تلقائيا بفضل نافذة ازدحام (Congestion Window – cwnd).

تضبط الخوارزميات الحديثة (مثل Reno وCUBIC أو BBR حسب أنظمة التشغيل) هذه النافذة لإيجاد توازن بين أقصى معدل واستقرار الشبكة.

كانت الإصدارات الأولى من TCP تستخدم أساسا آليتين :

  • Slow Start : زيادة أسية للمعدل حتى كشف ازدحام.

  • Congestion Avoidance : نمو أكثر حذرا بعد ذلك، خطي غالبا.

هذا التكيف الدائم من أسباب بقاء TCP فعالا رغم تفاوت جودة الشبكة.

إغلاق الاتصال

وخلافا لـUDP، يملك اتصال TCP أيضا إغلاقا نظيفا.

يغلق كل طرف تدفقه مستقلا بفضل علم FIN.

ويتطلب الإغلاق الكامل عادة أربعة تبادلات :

FIN
ACK
FIN
ACK

يضمن هذا الإجراء أن كل البيانات العابرة سُلّمت جيدا قبل تدمير الاتصال.

UDP : أقصى بساطة

يتبنى UDP (User Datagram Protocol) الفلسفة المعاكسة.

إنه بلا اتصال (connectionless).

لا يوجد :

  • أي handshake ؛

  • أي رقم تسلسل ؛

  • أي إشعار استلام ؛

  • أي إعادة إرسال ؛

  • أي تحكم في التدفق ؛

  • أي تحكم في الازدحام.

كل رسالة تُغلَّف ببساطة في datagramme مستقل، تُنقل إلى الشبكة، ثم ينساها المرسل.

Application → Datagramme UDP → IP → Internet

لا يحتفظ البروتوكول بأي حالة بين إرسالين.

وكل datagramme مستقل تماما عن سابقيه.

سلامة البيانات

رغم أن UDP لا يضمن التسليم ولا الترتيب، فإنه يحمي سلامة البيانات بفضل checksum.

عند الاستلام، يُعاد حساب الـchecksum.

  • إذا تطابقت القيمتان، يُقبل الـdatagramme.

  • وإلا، يُرفض فورا.

إذن يكشف UDP البيانات الفاسدة، لكنه لا يحاول أبدا استعادتها.

لماذا UDP سريع جدا ؟

ترويسة UDP لا تحوي إلا 8 octets، مقابل 20 octets كحد أدنى لـTCP (دون احتساب الخيارات مثل timestamps وSACK أو Window Scaling).

وبما أنه لا يُحافَظ على أي اتصال، لا يتعين على نظام التشغيل تتبع حالة كل تبادل، مما يقلل أيضا استهلاك الذاكرة وكost المعالجة.

يستلم التطبيق البيانات فور وصولها تقريبا، دون انتظار إعادات إرسال محتملة.

عندما يكون فقدان بيانة مفضلا

الفكرة الأساسية بسيطة :

معلومة قديمة قد تكون أقل قيمة من معلومة ضائعة.

خذ محادثة VoIP.

كل حزمة تحمل حوالي 20 ms من الصوت.

فإذا ضاعت حزمة، غالبا ما تستغرق إعادة إرسالها أكثر من تلك الـ20 ms.

وعندما تصل أخيرا، تكون المحادثة قد تقدمت فعلا.

تفضل معظم التطبيقات حينها إخفاء الفقدان (استيفاء، صمت، تصحيح خطأ) على انتظار إعادة الإرسال.

وينطبق المنطق نفسه على :

  • ألعاب اللاعبين المتعددين في الوقت الحقيقي ؛

  • بث الفيديو ؛

  • تدفقات القياس عن بعد ؛

  • حساسات IoT ؛

  • بيانات مواقع GPS.

القيمة الحديثة مفيدة دائما تقريبا أكثر من قيمة قديمة موثوقة تماما.

المستوى 2 : التشفير، TLS

لا يستبدل TLS (Transport Layer Security، خليفة SSL) محل TCP، بل يضاف فوقه. عمليا، يؤسس TLS اتصال TCP عاديا، ثم يتفاوض على جلسة مشفرة داخله : تبادل شهادات، واتفاق على خوارزمية تشفير، واشتقاق مفاتيح جلسة. وكل ما يعبر بعد ذلك مشفر ومصدَّق.

ثلاث ضمانات متميزة، كثيرا ما تُخلط :

  • السرية : لا يستطيع أحد غير الطرفين قراءة المحتوى.

  • السلامة : أي تغيير للبيانات أثناء العبور يُكتشف.

  • المصادقة : لكن في TLS التقليدي، باتجاه واحد : يتحقق العميل من أن الخادم هو فعلا من يدعي أنه هو (عبر شهادته، الموقعة من سلطة موثوقة)، لكن الخادم لا يتحقق من شيء حول هوية العميل. وهذا بالضبط نموذج HTTPS عندما تزور موقعا : المتصفح يصادق الموقع، والموقع لا يصادقك (مصادقة المستخدم تمر عبر آلية منفصلة، cookie جلسة أو token).

قلّص TLS 1.3 (الإصدار الحالي الموصى به) الـhandshake إلى ذهاب وإياب واحد في الحالة الشائعة، مقابل اثنين في TLS 1.2، مما يقلل زمن الاتصال بشكل محسوس.

المستوى 2 مكرر : mTLS، المصادقة تصبح متبادلة

mTLS (mutual TLS) هو TLS مع قيد إضافي : يطلب الخادم أيضا شهادة من العميل، ويتحقق منها. يثبت الطرفان هويتهما عبر شهادة موقعة من سلطة ثقة مشتركة.

وهي الآلية الطبيعية للتواصل خدمة لخدمة في بنية موزعة : فحيث يكفي HTTPS التقليدي ليتكلم متصفح مع خادم عام، يجيب mTLS عن سؤال مختلف ؛ كيف تعرف خدمة داخلية أنها تتكلم فعلا مع خدمة داخلية أخرى مرخصة، وليس مع مهاجم هبط على الشبكة ؟

Client                                          Serveur
  │──── ClientHello ─────────────────────────────▶│
  │◀─── ServerHello + certificat serveur ──────────│
  │──── vérifie le certificat serveur ─────────────│
  │──── envoie SON PROPRE certificat client ──────▶│
  │◀─── vérifie le certificat client ───────────────│
  │──── clés de session dérivées, canal chiffré ──▶│

مقابل mTLS تشغيلي : يلزم سلطة تصديق (CA) داخلية، وآلية توزيع شهادات لكل خدمة، واستراتيجية تدوير/إبطال. في بيئة آلة واحدة مع خدمات قليلة، يكون أحيانا تعقيدا أكثر من الفائدة، ويصبح mTLS ضروريا منذ اللحظة التي يعبر فيها الترافيك بين الخدمات شبكة لا نتحكم فيها كليا (عدة مضيفين، سحابة متعددة المستأجرين)، أو بمجرد أن نريد سياسة من نوع zero trust، حيث لا خدمة جديرة بالثقة ضمنيا لمجرد أنها "داخل" الشبكة.

المستوى 3 : البروتوكولات التطبيقية فوق TCP+TLS

بمجرد وضع النقل والتشفير، يبقى تحديد كيفية هيكلة التبادلات. وهذا دور البروتوكولات التطبيقية.

HTTP / HTTPS

HTTP بروتوكول طلب-جواب : يفتح العميل اتصالا (أو يعيد استخدام واحد، مع keep-alive)، ويرسل طلبا، وينتظر جوابا، ثم يمكن أن يُغلق الاتصال أو يُعاد استخدامه. HTTPS هو ببساطة HTTP على TLS، فالـS لا يغير شيئا في دلالة البروتوكول، فقط في كون النقل مشفرا.

لنموذج طلب-جواب حد بنيوي : لا يستطيع الخادم أبدا الكلام أولا. لا يستطيع إلا الرد على ما يطلبه العميل. وبالنسبة للـpolling المتكرر (التحقق من "هل من جديد ؟" كل ثانية)، يعمل لكنه يهدر الموارد، فكل طلب يعيد إنشاء عبء بروتوكولي، ليعلن في معظم الوقت أنه لا جديد.

WebSocket (WS / WSS)

يجيب WebSocket بالضبط عن هذا الحد. يبدأ الاتصال كطلب HTTP تقليدي (مع ترويسة Upgrade: websocket)، لكن بمجرد قبول المصافحة، لا يعود الاتصال TCP الكامن قناة طلب-جواب HTTP، بل يصبح قناة ثنائية الاتجاه full-duplex يستطيع فيها العميل والخادم إرسال رسائل في أي وقت، دون إعادة إصدار دورة طلب-جواب مع كل تبادل.

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

WSS هو ببساطة WebSocket على TLS، تماما كما HTTPS هو HTTP على TLS. وهو بروتوكول الاختيار لكل ما يتطلب دفع خادم في الوقت الحقيقي، دردشة وإشعارات وتدفقات تداول وأحداث ألعاب، دون الرغبة في إدارة بروتوكول ثنائي ذاتيا فوق TCP عارٍ.

gRPC

أقل شهرة خارج عالم الخدمات المصغرة لكنه محوري في التواصل خدمة لخدمة : يستند gRPC إلى HTTP/2 (أي TCP + TLS اختياري)، ويسلسل الرسائل بـProtocol Buffers (ثنائي ومُنمَّط ومضغوط، خلافا لـJSON النصي في معظم واجهات REST)، ويسمح أصلا بالبث ثنائي الاتجاه بفضل تعدد إرسال HTTP/2 (عدة تدفقات منطقية على اتصال TCP واحد، دون head-of-line blocking الذي كانت ستسببه عدة طلبات HTTP/1.1 متسلسلة).

QUIC / HTTP3

يغير QUIC قواعد اللعبة بالانطلاق من UDP بدلا من TCP في مستوى النقل، مع إعادة تنفيذ فوقه ضمانات الموثوقية التي كان TCP يقدمها أصلا، لكن تدفقا بتدفق بدلا من الشمول، مما يزيل head-of-line blocking في مستوى النقل (حزمة ضائعة في تدفق لم تعد تحجب التدفقات الأخرى لنفس الاتصال). TLS 1.3 مدمج مباشرة في QUIC بدلا من إضافته فوقه، مما يقلل زمن الـhandshake أكثر. وHTTP/3 هو HTTP فوق QUIC.

نظرة شاملة : أين يقع كل بروتوكول

طبقة بروتوكولات دور نقل TCP وUDP نقل البايتات، موثوقا أو لا نقل (جيل جديد) QUIC بموثوقية UDP + لكل تدفق + TLS مدمج أمان TLS وmTLS تشفير وسلامة ومصادقة (أحادية أو متبادلة) تطبيق HTTP/HTTPS وWS/WSS وgRPC هيكلة التبادلات (طلب-جواب، ثنائي الاتجاه، RPC مُنمَّط)

مثال ملموس لتثبيت الأفكار : بنية خدمات مصغرة مع لوحة ويب وخدمات داخلية يمكنها منطقيا الجمع بين HTTPS (لوحة ← API عامة، مصادقة أحادية الاتجاه كافية جهة المتصفح)، وmTLS (خدمة ← خدمة داخليا، مصادقة متبادلة لازمة)، وWSS (إشعارات وقت حقيقي مدفوعة نحو اللوحة)، ثلاثة بروتوكولات تطبيقية مختلفة، كلها مبنية على نفس الأساس TCP + TLS.

كيف تختار، عمليا

ثلاثة أسئلة تكفي غالبا للحسم :

  1. هل أحتاج الموثوقية والترتيب، أم أن حداثة البيانة تسبق تسليمها المضمون ؟ ← TCP إذا نعم، وUDP إذا لا (أو QUIC للجمع بينهما عبر حل وسط مختلف).

  2. هل يجب أن يستطيع الخادم بدء الرسائل، أم أن العميل هو دائما صاحب الطلب الأول ؟ ← WebSocket/بث gRPC إذا كان الخادم يجب أن يدفع، وHTTP تقليدي إلا ذلك.

  3. هل يجب أن يثبت الطرفان هويتهما لبعضهما، أم أن واحدا فقط يحتاج التحقق ؟ ← mTLS لخدمة لخدمة في بيئة zero-trust، وTLS بسيط لعميل عام تقليدي.

يزداد التعقيد التشغيلي مع كل طبقة مضافة، فـTCP العاري بلا بنية تحتية تُدار، وTLS يتطلب شهادات، وmTLS يتطلب CA واستراتيجية تدوير، وgRPC يتطلب تعريف مخطط Protobuf مشتركا. والمنعكس الصحيح هو ألا نصعد في التعقيد إلا عندما تُظهر الطبقة الدنيا حدا ملموسا، لا استباقا.

Máy móc nói chuyện với nhau thế nào : tour từ TCP tới mTLS

Vì sao TCP, UDP, TLS, mTLS, HTTP và WebSocket không phải lựa chọn cạnh tranh mà là các lớp chồng nhau; tour phân cấp về giao tiếp máy với máy, từ vận chuyển thô tới xác thực lẫn nhau.

Vấn đề : quá nhiều chữ viết tắt, quá ít phân cấp

TCP, UDP, TLS, mTLS, WebSocket, HTTP, HTTPS, gRPC, QUIC; hầu hết tài liệu nói về chúng trình bày chúng như danh sách phẳng các lựa chọn thay thế nhau, "chọn tùy ca dùng". Thực tế chúng không cùng mặt phẳng : vài cái là giao thức vận chuyển, vài cái là lớp bảo mật quấn quanh vận chuyển, vài cái nữa là giao thức ứng dụng dựa trên hai thứ đầu. Hiểu phân cấp là hiểu vì sao ta không bao giờ "chọn" giữa TCP và TLS: ta chọn TCP, rồi quyết có đặt TLS lên trên hay không.

Bài này dựng lại phân cấp đó lớp theo lớp, từ vận chuyển thô tới xác thực lẫn nhau, với mỗi tầng : nó đảm bảo gì, nó không đảm bảo gì, và khi nào cứ dùng nó là đủ.

Tầng 1 : vận chuyển (TCP đấu UDP)

Mọi thứ bắt đầu ở đây. TCP và UDP là hai giao thức chính của tầng Vận chuyển (Layer 4) trong mô hình OSI. Vai trò của chúng giống hệt : chở luồng dữ liệu giữa hai ứng dụng chạy trên các máy khác nhau. Thế nhưng cách chúng làm khác nhau triệt để.

Điều quan trọng cần hiểu là IP (Internet Protocol), nằm ở tầng mạng (Layer 3), chỉ định tuyến các gói từ máy này sang máy khác. Nó không đảm bảo chúng tới nơi, cũng không đảm bảo thứ tự, thậm chí không đảm bảo duy nhất. Các router chỉ ra quyết định định tuyến độc lập cho mỗi gói.

Chính sự thiếu đảm bảo này là thứ TCP tới bù đắp, trong khi UDP cố ý không thêm gì để giữ cực nhẹ.

TCP : tin cậy trước hết

TCP (Transmission Control Protocol) là giao thức hướng kết nối (connection-oriented). Trước khi trao đổi một byte dữ liệu, hai máy phải thiết lập kết nối logic.

Kết nối này tạo ra nhờ Three-Way Handshake nổi tiếng :


Client                           Serveur
SYN ---------------------------->
        <--------------------- SYN + ACK
ACK ---------------------------->
Connexion établie

Mỗi bước có mục tiêu chính xác :

  • SYN : client thông báo muốn mở kết nối và đưa số thứ tự đầu tiên (Initial Sequence Number - ISN).

  • SYN-ACK : máy chủ chấp nhận kết nối, xác nhận đã nhận SYN và đưa số thứ tự của chính nó.

  • ACK : client xác nhận đã nhận thông tin của máy chủ.

Từ lúc đó, hai máy biết trạng thái kết nối và có thể bắt đầu trao đổi dữ liệu.

Số thứ tự

TCP không nhìn dữ liệu như chuỗi gói nối tiếp, mà như luồng byte liên tục (byte stream).

Mỗi byte gửi đi có một số thứ tự.

Ví dụ :

Message :

Bonjour

B = octet 0
o = octet 1
n = octet 2
...

Nếu đoạn chứa các byte 1000 tới 1499 mất lúc vận chuyển, bên nhận có thể phát hiện chính xác thiếu gì.

Bên gửi chỉ truyền lại phần đó.

Độ hạt này là một trong những lý do TCP vững.

Xác nhận đã nhận (ACK)

Sau khi nhận dữ liệu, bên nhận gửi ACK (Acknowledgment).

Trái với điều ta thường tưởng, ACK không có nghĩa :

"Tôi đã nhận gói này"

Nó có nghĩa :

"Tôi đã nhận mọi byte tới số X."

Ví dụ :

Client envoie :

0 → 999

Serveur répond :

ACK = 1000

Nghĩa là :

"Mọi thứ trước byte 1000 đã tới nơi ổn."

Cơ chế này cho phép xác nhận nhiều đoạn cùng lúc (cumulative acknowledgments), giảm số gói điều khiển.

Truyền lại

Nếu ACK không bao giờ tới, TCP cho rằng đoạn mất.

Nó tự truyền lại.

Trễ truyền lại (Retransmission Timeout – RTO) không cố định.

TCP liên tục đo thời gian khứ hồi (RTT) nhờ các ACK nhận được và tính động RTO để tránh truyền lại vô ích.

Các triển khai hiện đại còn dùng cơ chế như Fast Retransmit : khi bên gửi nhận nhiều ACK trùng (thường ba), nó suy ra đoạn trung gian mất và gửi lại ngay, không chờ hết timer.

Sắp xếp lại gói

Internet hoàn toàn không đảm bảo hai gói đi cùng đường.

Ví dụ :

Paquet 1
Paris
  ↓
Londres
  ↓
New York

Paquet 2
Paris
  ↓
Francfort
  ↓
Chicago
  ↓
New York

Gói thứ hai có thể tới trước gói đầu.

TCP khi đó tạm lưu các đoạn nhận lộn xộn trong bộ đệm (reassembly buffer), rồi ráp lại trước khi giao cho ứng dụng.

Với ứng dụng, mọi thứ dường như tới hoàn hảo đúng thứ tự.

Kiểm soát luồng

Kết nối không chỉ phụ thuộc mạng.

Bên nhận cũng có dung lượng bộ nhớ giới hạn.

Nếu nó nhận nhanh hơn khả năng xử lý dữ liệu, bộ đệm của nó cuối cùng bão hòa.

TCP giải bài toán này bằng cửa sổ trượt (Sliding Window).

Bên nhận chỉ trong mỗi ACK :

Window = 32768 octets

Nghĩa là :

"Bạn có thể gửi tôi thêm tới 32 Ko."

Nếu cửa sổ này rớt về không :

Window = 0

Bên gửi tạm dừng truyền tới khi bên nhận thông báo cửa sổ mới có sẵn.

Cơ chế này tạo thành kiểm soát luồng (Flow Control) và ngăn máy nhanh làm ngập máy chậm hơn.

Kiểm soát tắc nghẽn

Ngay cả khi bên nhận đủ khả năng hấp thụ dữ liệu, bản thân mạng có thể bão hòa.

Các router có hàng đợi (queues) giới hạn.

Khi chúng tràn, các gói bị loại.

TCP diễn giải mất mát như dấu hiệu tắc nghẽn và tự thích ứng tốc độ bằng cửa sổ tắc nghẽn (Congestion Window – cwnd).

Các thuật toán hiện đại (như Reno, CUBIC hay BBR, tùy hệ điều hành) chỉnh cửa sổ này để tìm cân bằng giữa tốc độ tối đa và ổn định mạng.

Các phiên bản TCP đầu chủ yếu dùng hai cơ chế :

  • Slow Start : tăng tốc độ theo hàm mũ tới khi phát hiện tắc nghẽn.

  • Congestion Avoidance : sau đó tăng thận trọng hơn, thường tuyến tính.

Thích ứng thường trực này là một trong những lý do TCP vẫn hiệu quả dù chất lượng mạng biến động.

Đóng kết nối

Không như UDP, kết nối TCP còn có đóng sạch.

Mỗi đầu đóng độc lập luồng của mình bằng cờ FIN.

Đóng đầy đủ thường cần bốn lần trao đổi :

FIN
ACK
FIN
ACK

Thủ tục này đảm bảo mọi dữ liệu đang đi đã được giao trước khi hủy kết nối.

UDP : đơn giản tối đa

UDP (User Datagram Protocol) theo triết lý ngược.

Nó phi kết nối (connectionless).

Nó không có :

  • handshake nào ;

  • số thứ tự nào ;

  • xác nhận đã nhận nào ;

  • truyền lại nào ;

  • kiểm soát luồng nào ;

  • kiểm soát tắc nghẽn nào.

Mỗi thông điệp đơn giản được bọc trong datagram độc lập, truyền cho mạng, rồi bị bên gửi quên.

Application → Datagramme UDP → IP → Internet

Giao thức không giữ trạng thái nào giữa hai lần gửi.

Mỗi datagram hoàn toàn độc lập với các cái trước.

Toàn vẹn dữ liệu

Dù UDP không đảm bảo giao hay thứ tự, nó vẫn bảo vệ toàn vẹn dữ liệu bằng checksum.

Lúc nhận, checksum được tính lại.

  • Nếu các giá trị khớp, datagram được chấp nhận.

  • Ngược lại, nó bị loại ngay.

UDP vì vậy phát hiện dữ liệu hỏng, nhưng không bao giờ cố phục hồi chúng.

Vì sao UDP nhanh vậy?

Header UDP chỉ chứa 8 byte, so với tối thiểu 20 byte cho TCP (chưa kể tùy chọn như timestamp, SACK hay Window Scaling).

Vì không duy trì kết nối nào, hệ điều hành không phải theo dõi trạng thái mỗi lần trao đổi, giảm tiêu thụ bộ nhớ và chi phí xử lý.

Ứng dụng nhận dữ liệu gần như ngay khi tới, không chờ truyền lại khả dĩ.

Khi mất dữ liệu lại tốt hơn

Ý nền đơn giản :

Thông tin cũ có thể ít giá trị hơn thông tin mất.

Lấy cuộc gọi VoIP.

Mỗi gói chở khoảng 20 ms giọng.

Nếu một gói mất, truyền lại nó thường tốn thời gian hơn 20 ms đó.

Khi nó cuối cùng tới, cuộc trò chuyện đã tiến tiếp.

Hầu hết ứng dụng khi đó thích che mất mát (nội suy, im lặng, sửa lỗi) hơn chờ truyền lại.

Lập luận tương tự áp dụng cho :

  • game nhiều người thời gian thực ;

  • streaming video ;

  • luồng đo xa ;

  • cảm biến IoT ;

  • dữ liệu vị trí GPS.

Giá trị mới gần như luôn hữu ích hơn giá trị cũ tin cậy hoàn hảo.

Tầng 2 : mã hóa, TLS

TLS (Transport Layer Security, hậu duệ SSL) không thay TCP, nó thêm lên trên. Cụ thể, TLS thiết lập kết nối TCP bình thường, rồi thương lượng phiên mã hóa bên trong : trao đổi chứng chỉ, thống nhất thuật toán mã hóa, dẫn xuất khóa phiên. Mọi thứ đi qua sau đó được mã hóa và xác thực.

Ba đảm bảo riêng, thường bị lẫn :

  • Bảo mật : không ai ngoài hai bên đọc được nội dung.

  • Toàn vẹn : mọi sửa đổi dữ liệu lúc đi bị phát hiện.

  • Xác thực : nhưng trong TLS cổ điển, một chiều : client kiểm tra máy chủ đúng là thứ nó xưng (qua chứng chỉ của nó, do cơ quan tin cậy ký), nhưng máy chủ không kiểm tra gì về danh tính client. Đó đúng là mô hình HTTPS khi bạn thăm trang : trình duyệt xác thực trang, trang không xác thực bạn (xác thực người dùng đi qua cơ chế riêng, cookie phiên, token).

TLS 1.3 (phiên bản hiện khuyên dùng) đã rút handshake còn một lần khứ hồi trong ca thường, so với hai lần ở TLS 1.2, giảm đáng kể trễ kết nối.

Tầng 2bis : mTLS -- xác thực thành lẫn nhau

mTLS (mutual TLS) là TLS với ràng buộc thêm : máy chủ cũng đòi chứng chỉ từ client, và kiểm tra nó. Cả hai bên chứng minh danh tính qua chứng chỉ do cơ quan tin cậy chung ký.

Đó là cơ chế tự nhiên cho giao tiếp service-tới-service trong kiến trúc phân tán : nơi HTTPS cổ điển đủ để trình duyệt nói với máy chủ công cộng, mTLS trả lời câu hỏi khác; làm sao một service nội bộ biết nó đang nói với một service nội bộ được phép khác, chứ không phải kẻ tấn công vừa đáp xuống mạng?

Client                                          Serveur
  │──── ClientHello ─────────────────────────────▶│
  │◀─── ServerHello + certificat serveur ──────────│
  │──── vérifie le certificat serveur ─────────────│
  │──── envoie SON PROPRE certificat client ──────▶│
  │◀─── vérifie le certificat client ───────────────│
  │──── clés de session dérivées, canal chiffré ──▶│

Cái giá của mTLS mang tính vận hành : cần cơ quan chứng nhận (CA) nội bộ, cơ chế phân phối chứng chỉ cho mỗi service, và chiến lược xoay vòng/thu hồi. Trong môi trường đơn máy với ít service, đôi khi phức tạp hơn lợi ích -- mTLS thành cần thiết từ lúc lưu lượng liên service đi qua mạng ta không kiểm soát hoàn toàn (nhiều máy, cloud multi-tenant), hay hễ ta muốn chính sách kiểu zero trust, nơi không service nào ngầm đáng tin chỉ vì nó "ở trong" mạng.

Tầng 3 : giao thức ứng dụng trên TCP+TLS

Khi vận chuyển và mã hóa đã đặt, còn phải định nghĩa cách cấu trúc trao đổi. Đó là vai trò của giao thức ứng dụng.

HTTP / HTTPS

HTTP là giao thức yêu cầu-phản hồi : client mở kết nối (hay tái dùng, với keep-alive), gửi yêu cầu, chờ phản hồi, kết nối sau đó có thể đóng hay tái dùng. HTTPS, đơn giản là HTTP trên TLS -- chữ S không đổi gì ngữ nghĩa giao thức, chỉ đổi việc vận chuyển được mã hóa.

Mô hình yêu cầu-phản hồi có giới hạn cấu trúc : máy chủ không bao giờ được nói trước. Nó chỉ trả lời điều client hỏi. Với polling dày (kiểm tra "có gì mới?" mỗi giây), việc đó chạy nhưng phí tài nguyên -- mỗi yêu cầu tạo lại chi phí giao thức trong khi phần lớn thời gian chẳng có gì mới để thông báo.

WebSocket (WS / WSS)

WebSocket trả lời đúng giới hạn này. Kết nối khởi đầu như yêu cầu HTTP cổ điển (với header Upgrade: websocket), nhưng một khi bắt tay được chấp nhận, kết nối TCP bên dưới không còn là kênh yêu cầu-phản hồi HTTP -- nó thành kênh hai chiều full-duplex nơi client và máy chủ có thể gửi thông điệp bất cứ lúc nào, không phải phát lại chu kỳ yêu cầu-phản hồi mỗi lần trao đổi.

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

WSS đơn giản là WebSocket trên TLS, đúng như HTTPS là HTTP trên TLS. Đó là giao thức chọn cho mọi thứ đòi push máy chủ thời gian thực -- chat, thông báo, luồng trading, sự kiện game -- mà không muốn tự quản giao thức nhị phân trên TCP trần.

gRPC

Ít biết ngoài thế giới microservices nhưng trung tâm trong giao tiếp service-tới-service : gRPC dựa trên HTTP/2 (nên TCP + TLS tùy chọn), tuần tự hóa thông điệp bằng Protocol Buffers (nhị phân, có kiểu, gọn - ngược với JSON văn bản của hầu hết API REST), và cho phép gốc streaming hai chiều nhờ ghép kênh của HTTP/2 (nhiều luồng logic trên một kết nối TCP, không head-of-line blocking như nhiều yêu cầu HTTP/1.1 nối tiếp).

QUIC / HTTP3

QUIC đổi cuộc chơi bằng cách khởi đầu từ UDP thay vì TCP ở tầng vận chuyển, đồng thời tái triển khai lên trên các đảm bảo tin cậy mà TCP vốn cho gốc - nhưng theo từng luồng thay vì toàn cục, loại bỏ head-of-line blocking ở tầng vận chuyển (gói mất trên một luồng không còn chặn các luồng khác của cùng kết nối). TLS 1.3 tích hợp thẳng vào QUIC thay vì thêm lên trên, giảm tiếp trễ bắt tay. HTTP/3 là HTTP trên QUIC.

Tổng quan : mỗi giao thức nằm đâu

Tầng Giao thức Vai trò Vận chuyển TCP, UDP Cho byte đi, tin cậy hay không Vận chuyển (thế hệ mới) QUIC UDP + tin cậy theo luồng + TLS tích hợp Bảo mật TLS, mTLS Mã hóa, toàn vẹn, xác thực (đơn hay lẫn nhau) Ứng dụng HTTP/HTTPS, WS/WSS, gRPC Cấu trúc trao đổi (yêu cầu-phản hồi, hai chiều, RPC có kiểu)

Ví dụ cụ thể để cố định ý : kiến trúc microservices với dashboard web và service nội bộ có thể hợp lý kết hợp HTTPS (dashboard ↔ API công cộng, xác thực một chiều đủ phía trình duyệt), mTLS (service ↔ service nội bộ, xác thực lẫn nhau cần thiết), và WSS (thông báo thời gian thực đẩy về dashboard) -- ba giao thức ứng dụng khác nhau, đều dựng trên cùng nền TCP + TLS.

Cách chọn, trong thực hành

Ba câu hỏi thường đủ để chốt :

  1. Tôi có cần tin cậy và thứ tự, hay độ tươi của dữ liệu quan trọng hơn giao đảm bảo? → TCP nếu có, UDP nếu không (hay QUIC để có cả hai qua thỏa hiệp khác).

  2. Máy chủ có phải chủ động gửi thông điệp, hay client luôn hỏi trước? → WebSocket/gRPC streaming nếu máy chủ phải đẩy, HTTP cổ điển nếu không.

  3. Cả hai bên có phải chứng minh danh tính lẫn nhau, hay chỉ một bên cần kiểm tra? → mTLS cho service-tới-service trong môi trường zero-trust, TLS đơn cho client công cộng cổ điển.

Độ phức tạp vận hành tăng mỗi lớp thêm, TCP trần không có hạ tầng nào cần quản, TLS đòi chứng chỉ, mTLS đòi CA và chiến lược xoay vòng, gRPC đòi định nghĩa schema Protobuf chia sẻ. Phản xạ đúng là chỉ leo phức tạp khi tầng dưới cho thấy giới hạn cụ thể, không phải phòng trước.

เครื่องจักรสื่อสารกันอย่างไร: ภาพรวมจาก TCP ถึง mTLS

ทำไม TCP, UDP, TLS, mTLS, HTTP และ WebSocket ไม่ใช่ทางเลือกที่แข่งขันกัน แต่เป็นชั้นที่ซ้อนทับกัน ภาพรวมเชิงลำดับชั้นของการสื่อสารระหว่างเครื่อง จากการขนส่งดิบไปจนถึงการพิสูจน์ตัวตนร่วมกัน

ปัญหา: คำย่อมากเกินไป ลำดับชั้นไม่เพียงพอ

TCP, UDP, TLS, mTLS, WebSocket, HTTP, HTTPS, gRPC, QUIC; แหล่งข้อมูลส่วนใหญ่ที่พูดถึงโปรโตคอลเหล่านี้มักนำเสนอเป็นรายการราบของตัวเลือกที่ใช้แทนกันได้ "ให้เลือกตามกรณีการใช้งาน" แต่ในความเป็นจริงแล้วพวกมันไม่ได้อยู่ในระนาบเดียวกัน บางตัวเป็นโปรโตคอลการขนส่ง บางตัวเป็นชั้นความปลอดภัยที่ห่อหุ้มอยู่รอบการขนส่ง และบางตัวเป็นโปรโตคอลระดับแอปพลิเคชันที่ทำงานบนสองประเภทแรก การเข้าใจลำดับชั้นคือการเข้าใจว่าทำไมเราไม่เคย "เลือก" ระหว่าง TCP กับ TLS: เราเลือก TCP จากนั้น จึงตัดสินใจว่าจะใส่ TLS ทับลงไปหรือไม่

บทความนี้สร้างลำดับชั้นนี้ขึ้นทีละชั้น จากการขนส่งดิบไปจนถึงการพิสูจน์ตัวตนร่วมกัน โดยในแต่ละระดับจะอธิบายว่า: มันรับประกันอะไรบ้าง, ไม่ได้รับประกันอะไรบ้าง, และเมื่อใดควรพอใจกับมัน

ระดับ 1: การขนส่ง (TCP เทียบกับ UDP)

ทุกอย่างเริ่มต้นที่นี่ TCP และ UDP เป็นโปรโตคอลหลักสองตัวของชั้น Transport (Layer 4) ในแบบจำลอง OSI บทบาทของพวกมันเหมือนกัน: ขนส่งสตรีมข้อมูลระหว่างสองแอปพลิเคชันที่ทำงานบนเครื่องคนละเครื่อง แต่วิธีการทำให้สำเร็จนั้นแตกต่างกันอย่างสิ้นเชิง

สิ่งสำคัญคือต้องเข้าใจว่า IP (Internet Protocol) ซึ่งอยู่ในชั้นเครือข่าย (Layer 3) นั้นทำเพียงส่งต่อแพ็กเกตจากโฮสต์หนึ่งไปยังอีกโฮสต์หนึ่ง มันไม่รับประกันว่าข้อมูลจะถึงปลายทาง ไม่รับประกันลำดับ หรือแม้แต่ความไม่ซ้ำกันของแพ็กเกต เราเตอร์จะตัดสินใจเส้นทางอย่างอิสระสำหรับแต่ละแพ็กเกต

การขาดการรับประกันนี้คือสิ่งที่ TCP เข้ามาชดเชย ในขณะที่ UDP เลือกที่จะไม่เพิ่มสิ่งใดเข้าไปโดยเจตนาเพื่อให้คงความเบาอย่างยิ่ง

TCP: ความน่าเชื่อถือเหนือสิ่งอื่นใด

TCP (Transmission Control Protocol) เป็นโปรโตคอล แบบเชื่อมต่อ (connection-oriented) ก่อนที่จะแลกเปลี่ยนข้อมูลแม้แต่ไบต์เดียว ทั้งสองเครื่องต้องสร้างการเชื่อมต่อเชิงตรรกะก่อน

การเชื่อมต่อนี้ถูกสร้างขึ้นผ่าน Three-Way Handshake อันโด่งดัง:

Client                           Server
SYN ---------------------------->
        <--------------------- SYN + ACK
ACK ----------------------------> 
Connection established

แต่ละขั้นตอนมีวัตถุประสงค์ที่ชัดเจน:

  • SYN: ไคลเอนต์ประกาศว่าต้องการเปิดการเชื่อมต่อและให้หมายเลขลำดับเริ่มต้น (Initial Sequence Number - ISN)

  • SYN-ACK: เซิร์ฟเวอร์ยอมรับการเชื่อมต่อ รับทราบ SYN และให้หมายเลขลำดับของตนเอง

  • ACK: ไคลเอนต์ยืนยันการรับข้อมูลของเซิร์ฟเวอร์

จากจุดนี้เป็นต้นไป ทั้งสองเครื่องจะรู้สถานะของการเชื่อมต่อและสามารถเริ่มแลกเปลี่ยนข้อมูลได้

หมายเลขลำดับ (Sequence Numbers)

TCP ไม่มองข้อมูลเป็นลำดับของแพ็กเกต แต่มองเป็น สตรีมไบต์ต่อเนื่อง (byte stream)

แต่ละไบต์ที่ส่งไปจะมีหมายเลขลำดับ

ตัวอย่าง:

Message:

Bonjour

B = byte 0
o = byte 1
n = byte 2
...

หากเซกเมนต์ที่มีไบต์ 1000 ถึง 1499 สูญหายไประหว่างการขนส่ง ผู้รับสามารถตรวจจับได้อย่างแม่นยำว่าส่วนใดหายไป

ผู้ส่งจะส่งซ้ำเฉพาะส่วนนั้นเท่านั้น

ความละเอียดระดับนี้เป็นหนึ่งในเหตุผลที่ทำให้ TCP มีความแข็งแกร่ง

การตอบรับ (ACK)

หลังจากรับข้อมูลแล้ว ผู้รับจะส่ง ACK (Acknowledgment)

ตรงกันข้ามกับสิ่งที่หลายคนมักคิด ACK ไม่ได้หมายความว่า:

"ฉันได้รับแพ็กเกตนี้แล้ว"

แต่หมายถึง:

"ฉันได้รับไบต์ทั้งหมดจนถึงหมายเลข X แล้ว"

ตัวอย่าง:

Client sends:

0 → 999

Server responds:

ACK = 1000

นั่นหมายถึง:

"ทุกอย่างที่อยู่ก่อนไบต์ที่ 1000 มาถึงแล้ว"

กลไกนี้ช่วยให้สามารถรับทราบหลายเซกเมนต์พร้อมกันได้ (cumulative acknowledgments) ซึ่งลดจำนวนแพ็กเกตควบคุม

การส่งซ้ำ (Retransmissions)

หาก ACK ไม่เคยมาถึง TCP จะถือว่าเซกเมนต์นั้นสูญหาย

มันจะส่งซ้ำโดยอัตโนมัติ

ระยะเวลารอก่อนส่งซ้ำ (Retransmission Timeout – RTO) ไม่ใช่ค่าคงที่

TCP จะวัดระยะเวลาไป-กลับ (RTT) อย่างต่อเนื่องจาก ACK ที่ได้รับ และคำนวณ RTO แบบไดนามิกเพื่อหลีกเลี่ยงการส่งซ้ำที่ไม่จำเป็น

การใช้งานสมัยใหม่ยังใช้กลไกเช่น Fast Retransmit: เมื่อผู้ส่งได้รับ ACK ซ้ำๆ หลายครั้ง (โดยทั่วไปสามครั้ง) มันจะสรุปว่าเซกเมนต์ที่อยู่ระหว่างกลางสูญหายและส่งซ้ำทันที โดยไม่ต้องรอให้ตัวจับเวลาหมดอายุ

การจัดเรียงแพ็กเกตใหม่ (Packet Reordering)

อินเทอร์เน็ตไม่รับประกันอย่างเด็ดขาดว่าแพ็กเกตสองแพ็กเกตจะเดินทางตามเส้นทางเดียวกัน

ตัวอย่าง:

Packet 1
Paris
 ↓
London
 ↓
New York

Packet 2
Paris
 ↓
Frankfurt
 ↓
Chicago
 ↓
New York

แพ็กเกตที่สองอาจมาถึงก่อนแพ็กเกตแรก

TCP จะเก็บเซกเมนต์ที่ได้รับ แบบไม่เรียงลำดับ ไว้ชั่วคราวในบัฟเฟอร์ (reassembly buffer) จากนั้นจึงประกอบกลับเข้าที่ก่อนส่งให้แอปพลิเคชัน

สำหรับแอปพลิเคชันแล้ว ทุกอย่างดูเหมือนมาถึงอย่างถูกต้องตามลำดับ

การควบคุมการไหล (Flow Control)

การเชื่อมต่อไม่ได้ขึ้นอยู่กับเครือข่ายเท่านั้น

ผู้รับก็มีความจุหน่วยความจำที่จำกัดเช่นกัน

หากได้รับข้อมูลเร็วกว่าที่จะประมวลผลได้ บัฟเฟอร์จะเต็มในที่สุด

TCP แก้ปัญหานี้ด้วย หน้าต่างเลื่อน (Sliding Window)

ผู้รับจะระบุในทุก ACK:

Window = 32768 bytes

นั่นหมายถึง:

"คุณสามารถส่งเพิ่มได้อีกถึง 32 KB"

หากหน้าต่างนี้ลดลงเป็นศูนย์:

Window = 0

ผู้ส่งจะหยุดส่งชั่วคราวจนกว่าผู้รับจะประกาศว่ามีหน้าต่างว่างอีกครั้ง

กลไกนี้คือ การควบคุมการไหล (Flow Control) และป้องกันไม่ให้โฮสต์ที่เร็วท่วมโฮสต์ที่ช้า

การควบคุมความแออัด (Congestion Control)

แม้ว่าผู้รับจะสามารถรับข้อมูลได้ แต่เครือข่ายเองก็อาจอิ่มตัวได้

เราเตอร์มีคิว (queues) ที่จำกัด

เมื่อคิวล้น แพ็กเกตจะถูกลบทิ้ง

TCP ตีความการสูญหายเป็นสัญญาณของความแออัดและปรับอัตราการส่งโดยอัตโนมัติผ่าน หน้าต่างความแออัด (Congestion Window – cwnd)

อัลกอริทึมสมัยใหม่ (เช่น Reno, CUBIC หรือ BBR ขึ้นอยู่กับระบบปฏิบัติการ) จะปรับหน้าต่างนี้เพื่อหาสมดุลระหว่างอัตราการส่งสูงสุดและเสถียรภาพของเครือข่าย

TCP รุ่นแรกๆ ใช้กลไกหลักสองอย่าง:

  • Slow Start: เพิ่มอัตราการส่งแบบทวีคูณจนกระทั่งตรวจพบความแออัด

  • Congestion Avoidance: จากนั้นเติบโตอย่างระมัดระวังมากขึ้น โดยทั่วไปเป็นแบบเส้นตรง

การปรับตัวอย่างต่อเนื่องนี้เป็นหนึ่งในเหตุผลที่ TCP ยังคงมีประสิทธิภาพแม้คุณภาพเครือข่ายจะผันผวน

การปิดการเชื่อมต่อ

ต่างจาก UDP การเชื่อมต่อ TCP มีการปิดที่ชัดเจน

แต่ละปลายทางจะปิดสตรีมของตนเองอย่างอิสระผ่านแฟล็ก FIN

การปิดสมบูรณ์จำเป็นต้องมีการแลกเปลี่ยนสี่ครั้ง:

FIN
ACK
FIN
ACK

ขั้นตอนนี้รับประกันว่าข้อมูลทั้งหมดที่กำลังเดินทางอยู่จะถูกส่งถึงก่อนที่จะทำลายการเชื่อมต่อ

UDP: ความเรียบง่ายสูงสุด

UDP (User Datagram Protocol) ใช้ปรัชญาตรงกันข้าม

มัน ไม่ต้องมีการเชื่อมต่อ (connectionless)

ไม่มี:

  • ไม่มีการจับมือ (handshake)

  • ไม่มีหมายเลขลำดับ

  • ไม่มีการตอบรับ

  • ไม่มีการส่งซ้ำ

  • ไม่มีการควบคุมการไหล

  • ไม่มีการควบคุมความแออัด

แต่ละข้อความจะถูกห่อหุ้มใน ดาตาแกรม (datagram) อิสระ ส่งไปยังเครือข่าย แล้วผู้ส่งก็ลืมมัน

Application → UDP Datagram → IP → Internet

โปรโตคอลไม่เก็บสถานะใดๆ ระหว่างการส่งสองครั้ง

แต่ละดาตาแกรมเป็นอิสระจากดาตาแกรมก่อนหน้าอย่างสมบูรณ์

ความสมบูรณ์ของข้อมูล (Data Integrity)

แม้ว่า UDP จะไม่รับประกันการส่งถึงหรือลำดับ แต่มันก็ยังปกป้องความสมบูรณ์ของข้อมูลด้วย checksum

เมื่อรับข้อมูลแล้ว checksum จะถูกคำนวณใหม่

  • หากค่าตรงกัน ดาตาแกรมจะถูกยอมรับ

  • หากไม่ตรงกัน ดาตาแกรมจะถูกปฏิเสธทันที

UDP จึงตรวจจับข้อมูลที่เสียหายได้ แต่ไม่เคยพยายามกู้คืน

ทำไม UDP ถึงเร็วขนาดนี้?

ส่วนหัว UDP มีเพียง 8 ไบต์ เทียบกับขั้นต่ำ 20 ไบต์ สำหรับ TCP (ไม่นับตัวเลือกต่างๆ เช่น timestamps, SACK หรือ Window Scaling)

ไม่มีการรักษาการเชื่อมต่อ ระบบปฏิบัติการจึงไม่ต้องติดตามสถานะของการแลกเปลี่ยนแต่ละครั้ง ซึ่งลดการใช้หน่วยความจำและต้นทุนการประมวลผล

แอปพลิเคชันได้รับข้อมูลเกือบจะทันทีที่มาถึง โดยไม่ต้องรอการส่งซ้ำที่อาจเกิดขึ้น

เมื่อใดที่การสูญเสียข้อมูลดีกว่า

แนวคิดพื้นฐานนั้นง่าย:

ข้อมูลที่เก่าอาจมีค่าน้อยกว่าข้อมูลที่สูญหาย

ลองนึกถึงการสนทนา VoIP

แต่ละแพ็กเกตนำส่งเสียงประมาณ 20 ms

หากแพ็กเกตสูญหาย การส่งซ้ำมักใช้เวลานานกว่า 20 ms เหล่านั้น

เมื่อมันมาถึงในที่สุด การสนทนาก็เดินหน้าไปแล้ว

แอปพลิเคชันส่วนใหญ่จึงเลือกที่จะปกปิดการสูญหาย (การแทรกสัญญาณ, ความเงียบ, การแก้ไขข้อผิดพลาด) แทนที่จะรอการส่งซ้ำ

เหตุผลเดียวกันนี้ใช้กับ:

  • เกมแบบหลายผู้เล่นเวลาจริง

  • การสตรีมวิดีโอ

  • สตรีมเทเลเมทรี

  • เซ็นเซอร์ IoT

  • ข้อมูลตำแหน่ง GPS

ค่าใหม่ล่าสุดมักจะมีประโยชน์มากกว่าค่าเก่าที่สมบูรณ์แบบเสมอ

ระดับ 2: การเข้ารหัส, TLS

TLS (Transport Layer Security, ผู้สืบทอดของ SSL) ไม่ได้แทนที่ TCP แต่มาเพิ่มทับไว้ข้างบน ในทางปฏิบัติ TLS จะสร้างการเชื่อมต่อ TCP ปกติ จากนั้นจึงเจรจาเซสชันที่เข้ารหัสภายใน: แลกเปลี่ยนใบรับรอง, ตกลงเกี่ยวกับอัลกอริทึมการเข้ารหัส, สร้างคีย์เซสชัน ทุกสิ่งที่ส่งผ่านหลังจากนั้นจะถูกเข้ารหัสและรับรองความถูกต้อง

การรับประกันสามประการที่แตกต่างกัน ซึ่งมักถูกสับสน:

  • การรักษาความลับ (Confidentiality): ไม่มีใครอื่นนอกจากทั้งสองฝ่ายสามารถอ่านเนื้อหาได้

  • ความสมบูรณ์ (Integrity): การเปลี่ยนแปลงใดๆ ของข้อมูลระหว่างการส่งจะถูกตรวจจับ

  • การพิสูจน์ตัวตน (Authentication): แต่ใน TLS แบบทั่วไป เป็นแบบทิศทางเดียว: ไคลเอนต์ตรวจสอบว่าเซิร์ฟเวอร์เป็นอย่างที่มันอ้างจริง (ผ่านใบรับรองที่ลงนามโดยหน่วยงานที่เชื่อถือได้) แต่เซิร์ฟเวอร์ไม่ได้ตรวจสอบอะไรเกี่ยวกับตัวตนของไคลเอนต์ นี่คือโมเดลของ HTTPS เมื่อคุณเยี่ยมชมเว็บไซต์: เบราว์เซอร์ยืนยันตัวตนของเว็บไซต์ เว็บไซต์ไม่ได้ยืนยันตัวตนของคุณ (การยืนยันตัวตนผู้ใช้จะผ่านกลไกแยกต่างหาก เช่น คุกกี้เซสชัน หรือโทเค็น)

TLS 1.3 (เวอร์ชันปัจจุบันที่แนะนำ) ได้ลดการจับมือเหลือเพียงหนึ่งรอบไป-กลับในกรณีปกติ เทียบกับสองครั้งใน TLS 1.2 ซึ่งช่วยลดความหน่วงในการเชื่อมต่อได้อย่างมาก

ระดับ 2bis: mTLS -- การพิสูจน์ตัวตนกลายเป็นร่วมกัน

mTLS (mutual TLS) คือ TLS ที่มีข้อกำหนดเพิ่มเติม: เซิร์ฟเวอร์จะ ต้องการ ใบรับรองจากไคลเอนต์ด้วย และตรวจสอบมัน ทั้งสองฝ่ายพิสูจน์ตัวตนผ่านใบรับรองที่ลงนามโดยหน่วยงานที่เชื่อถือได้ร่วมกัน

นี่คือกลไกธรรมชาติสำหรับการสื่อสารระหว่างบริการในสถาปัตยกรรมแบบกระจาย: ในขณะที่ HTTPS ทั่วไปเพียงพอสำหรับให้เบราว์เซอร์คุยกับเซิร์ฟเวอร์สาธารณะ mTLS ตอบคำถามที่แตกต่างออกไป บริการภายในจะรู้ได้อย่างไรว่ามันกำลังคุยกับบริการภายในอื่นที่ได้รับอนุญาตจริงๆ ไม่ใช่ผู้โจมตีที่เข้ามาในเครือข่าย?

Client                                          Server
  │──── ClientHello ─────────────────────────────▶│
  │◀─── ServerHello + server certificate ──────────│
  │──── verifies server certificate ──────────────│
  │──── sends ITS OWN client certificate ────────▶│
  │◀─── verifies client certificate ──────────────│
  │──── session keys derived, encrypted channel ─▶│

ข้อเสียของ mTLS คือในทางปฏิบัติ: ต้องมีหน่วยงานออกใบรับรอง (CA) ภายใน, กลไกการแจกจ่ายใบรับรองให้แต่ละบริการ, และกลยุทธ์การหมุนเวียน/เพิกถอน ในสภาพแวดล้อมเครื่องเดียวที่มีบริการไม่กี่ตัว บางครั้งก็ซับซ้อนเกินกว่าประโยชน์ที่ได้ -- mTLS จำเป็นเมื่อการรับส่งระหว่างบริการต้องผ่านเครือข่ายที่เราไม่ได้ควบคุมอย่างสมบูรณ์ (หลายโฮสต์, คลาวด์แบบหลายผู้เช่า) หรือเมื่อต้องการนโยบายแบบ zero trust ที่ไม่มีบริการใดได้รับความไว้วางใจโดยปริยายเพียงเพราะมัน "อยู่ใน" เครือข่าย

ระดับ 3: โปรโตคอลระดับแอปพลิเคชันบน TCP+TLS

เมื่อมีการขนส่งและการเข้ารหัสแล้ว ก็ถึงเวลากำหนด วิธีการจัดโครงสร้างการแลกเปลี่ยน นี่คือบทบาทของโปรโตคอลระดับแอปพลิเคชัน

HTTP / HTTPS

HTTP เป็นโปรโตคอลแบบร้องขอ-ตอบกลับ: ไคลเอนต์เปิดการเชื่อมต่อ (หรือใช้ซ้ำกับ keep-alive), ส่งคำขอ, รอการตอบกลับ, จากนั้นการเชื่อมต่อจะปิดหรือถูกใช้ซ้ำ HTTPS ก็คือ HTTP บน TLS -- S ไม่ได้เปลี่ยนแปลงความหมายของโปรโตคอล เพียงแต่การขนส่งถูกเข้ารหัส

โมเดลร้องขอ-ตอบกลับมีข้อจำกัดเชิงโครงสร้าง: เซิร์ฟเวอร์ไม่สามารถพูดก่อนได้เลย มันทำได้เพียงตอบสนองต่อสิ่งที่ไคลเอนต์ขอ สำหรับการสอบถามถี่ๆ (ตรวจสอบ "มีอะไรใหม่ไหม?" ทุกวินาที) มันใช้ได้แต่สิ้นเปลืองทรัพยากร -- แต่ละคำขอสร้างค่าใช้จ่ายของโปรโตคอลซ้ำแล้วซ้ำเล่า โดยส่วนใหญ่แล้วก็ไม่มีอะไรใหม่จะประกาศ

WebSocket (WS / WSS)

WebSocket ตอบโจทย์ข้อจำกัดนี้พอดี การเชื่อมต่อเริ่มต้นเป็นคำขอ HTTP ทั่วไป (ด้วยส่วนหัว Upgrade: websocket) แต่เมื่อการจับมือได้รับการยอมรับแล้ว การเชื่อมต่อ TCP ที่อยู่ข้างใต้จะไม่ใช่ช่องทางร้องขอ-ตอบกลับแบบ HTTP อีกต่อไป -- มันกลายเป็นช่องทางสองทิศทางแบบ full-duplex ที่ทั้งไคลเอนต์และเซิร์ฟเวอร์สามารถส่งข้อความได้ตลอดเวลา โดยไม่ต้องส่งรอบร้องขอ-ตอบกลับซ้ำในทุกการแลกเปลี่ยน

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

WSS ก็คือ WebSocket บน TLS เช่นเดียวกับ HTTPS คือ HTTP บน TLS เป็นโปรโตคอลที่เหมาะสมสำหรับทุกอย่างที่ต้องการ push จากเซิร์ฟเวอร์แบบเวลาจริง -- แชท, การแจ้งเตือน, สตรีมการซื้อขาย, อีเวนต์เกม -- โดยไม่ต้องจัดการโปรโตคอลไบนารีเองบน TCP เปลือย

gRPC

รู้จักกันน้อยนอกโลกไมโครเซอร์วิสแต่เป็นศูนย์กลางในการสื่อสารระหว่างบริการ: gRPC ทำงานบน HTTP/2 (ดังนั้น TCP + TLS เลือกได้), ทำให้ข้อความเป็นอนุกรมด้วย Protocol Buffers (ไบนารี, มีชนิด, กะทัดรัด - ตรงข้ามกับ JSON ข้อความของ API REST ส่วนใหญ่), และรองรับสตรีมมิ่งสองทิศทางโดยธรรมชาติผ่านการมัลติเพล็กซ์ของ HTTP/2 (หลายสตรีมเชิงตรรกะบนการเชื่อมต่อ TCP เดียว โดยไม่มี head-of-line blocking ที่เกิดจากคำขอ HTTP/1.1 แบบเรียงลำดับหลายรายการ)

QUIC / HTTP3

QUIC เปลี่ยนเกมด้วยการเริ่มจาก UDP แทนที่จะเป็น TCP ในระดับการขนส่ง ขณะเดียวกันก็ใช้การรับประกันความน่าเชื่อถือที่ TCP มีมาแต่เดิมขึ้นมาใหม่บน UDP -- แต่ทำทีละสตรีมแทนที่จะทำโดยรวม ซึ่งช่วยขจัด head-of-line blocking ในระดับการขนส่ง (แพ็กเกตที่สูญหายในสตรีมหนึ่งจะไม่บล็อกสตรีมอื่นในการเชื่อมต่อเดียวกัน) TLS 1.3 ถูกรวมเข้าไปใน QUIC โดยตรงแทนที่จะเพิ่มทับข้างบน ซึ่งช่วยลดความหน่วงในการจับมือลงอีก HTTP/3 คือ HTTP บน QUIC

ภาพรวม: โปรโตคอลแต่ละตัวอยู่ที่ไหน

Layer Protocols Role Transport TCP, UDP ขนส่งไบต์ ไม่ว่าจะเชื่อถือได้หรือไม่ Transport (รุ่นใหม่) QUIC UDP + ความน่าเชื่อถือต่อสตรีม + TLS ในตัว Security TLS, mTLS การเข้ารหัส, ความสมบูรณ์, การพิสูจน์ตัวตน (ทางเดียวหรือร่วมกัน) Application HTTP/HTTPS, WS/WSS, gRPC จัดโครงสร้างการแลกเปลี่ยน (ร้องขอ-ตอบกลับ, สองทิศทาง, RPC แบบมีชนิด)

ตัวอย่างที่เป็นรูปธรรม: สถาปัตยกรรมไมโครเซอร์วิสที่มี dashboard เว็บและบริการภายในอาจใช้ HTTPS ร่วมกันอย่างเหมาะสม (dashboard ↔ API สาธารณะ, การยืนยันตัวตนทางเดียวก็เพียงพอสำหรับฝั่งเบราว์เซอร์), mTLS (บริการ ↔ บริการภายใน, จำเป็นต้องยืนยันตัวตนร่วมกัน), และ WSS (การแจ้งเตือนเวลาจริงที่ push ไปยัง dashboard) -- โปรโตคอลระดับแอปพลิเคชันสามแบบที่แตกต่างกัน แต่ทั้งหมดสร้างบนฐาน TCP + TLS เดียวกัน

วิธีเลือกในทางปฏิบัติ

คำถามสามข้อก็เพียงพอที่จะตัดสินใจ:

  1. ฉันต้องการความน่าเชื่อถือและลำดับ หรือความสดของข้อมูลสำคัญกว่าการรับประกันการส่งถึง? → TCP ถ้าใช่, UDP ถ้าไม่ใช่ (หรือ QUIC เพื่อได้ทั้งสองอย่างผ่านการประนีประนอมที่แตกต่าง)

  2. เซิร์ฟเวอร์ต้องสามารถเริ่มส่งข้อความได้ หรือไคลเอนต์เป็นฝ่ายร้องขอแรกเสมอ? → WebSocket/gRPC streaming ถ้าเซิร์ฟเวอร์ต้อง push, HTTP ทั่วไปถ้าไม่

  3. ทั้งสองฝ่ายต้องพิสูจน์ตัวตนร่วมกัน หรือแค่ฝ่ายเดียวที่ต้องถูกตรวจสอบ? → mTLS สำหรับบริการถึงบริการในสภาพแวดล้อม zero-trust, TLS ธรรมดาสำหรับไคลเอนต์สาธารณะทั่วไป

ความซับซ้อนในทางปฏิบัติเพิ่มขึ้นในทุกชั้นที่เพิ่มเข้าไป: TCP เปลือยไม่มีโครงสร้างพื้นฐานใดต้องจัดการ, TLS ต้องใช้ใบรับรอง, mTLS ต้องใช้ CA และกลยุทธ์การหมุนเวียน, gRPC ต้องใช้คำจำกัดความสคีมา Protobuf ที่ใช้ร่วมกัน สัญชาตญาณที่ดีคือเพิ่มความซับซ้อนเมื่อชั้นล่างแสดงข้อจำกัดที่เป็นรูปธรรมเท่านั้น ไม่ใช่โดยการคาดการณ์ล่วงหน้า