Protocolo TCP: Fundamentos

No capítulo anterior, construímos protocolos de transferência confiável de dados (RDT) de forma incremental — do canal perfeito (rdt1.0) até soluções com pipeline como Go-Back-N e Repetição Seletiva. Esses conceitos são a base teórica para o protocolo que estudaremos agora: o TCP (Transmission Control Protocol). O TCP é o protocolo de transporte mais utilizado na Internet, responsável por garantir que dados cheguem corretamente, em ordem e sem perdas entre dois processos. Neste capítulo, vamos explorar seus fundamentos: características gerais, a estrutura do segmento TCP, o mecanismo de números de sequência e ACK cumulativo, a estimativa adaptativa de RTT e os cenários de retransmissão.

Visão Geral do TCP

O TCP é um protocolo de transporte com as seguintes características fundamentais:

  • Ponto-a-ponto: cada conexão TCP envolve exatamente um emissor e um receptor — não há multicast nem broadcast.
  • Full-duplex: os dados fluem em ambas as direções simultaneamente na mesma conexão. O Host A pode enviar dados para o Host B ao mesmo tempo que recebe dados de B.
  • Fluxo de bytes confiável e ordenado (reliable, in-order byte stream): a aplicação enxerga os dados como um fluxo contínuo de bytes, sem fronteiras de mensagem. O TCP garante que todos os bytes cheguem, na ordem correta.
  • Orientado a conexão (connection-oriented): antes de trocar dados, os dois hosts realizam um handshake para estabelecer a conexão e sincronizar parâmetros.
  • Com controle de fluxo: o emissor não sobrecarrega o receptor — a janela de recepção (receive window) limita a quantidade de dados em trânsito.

O TCP oferece a ilusão de um canal confiável e ordenado para a aplicação, mesmo que a camada de rede (IP) por baixo seja de melhor esforço — podendo perder, duplicar ou reordenar pacotes.

Buffers e Segmentação

Quando uma aplicação escreve dados no socket TCP, os bytes são armazenados no buffer de envio (send buffer). O TCP, por conta própria, decide quando e quantos bytes agrupar em um segmento para enviar pela rede. A quantidade máxima de dados em cada segmento é limitada pelo MSS (Maximum Segment Size).

ConceitoDefiniçãoValor Típico
MSS (Maximum Segment Size)Quantidade máxima de dados da aplicação em um segmento TCP (sem contar cabeçalhos)1460 bytes
MTU (Maximum Transmission Unit)Tamanho máximo do frame no nível de enlace (inclui todos os cabeçalhos)1500 bytes (Ethernet)
Send BufferBuffer onde o TCP armazena dados enviados pela aplicação, aguardando transmissão e confirmaçãoConfigurável pelo SO
Receive BufferBuffer onde o TCP armazena dados recebidos, aguardando leitura pela aplicaçãoConfigurável pelo SO

O MSS é calculado como: MSS = MTU − Cabeçalho IP − Cabeçalho TCP = 1500 − 20 − 20 = 1460 bytes (para Ethernet com cabeçalhos padrão).

Estrutura do Segmento TCP

O segmento TCP é a unidade de dados trocada entre dois hosts na camada de transporte. Assim como o UDP, o segmento TCP contém campos de porta de origem e porta de destino para multiplexação/demultiplexação. Porém, o cabeçalho TCP é significativamente mais complexo, refletindo os mecanismos de confiabilidade, controle de fluxo e controle de conexão.

CampoTamanhoFunção
Porta de Origem16 bitsIdentifica o processo remetente no host emissor
Porta de Destino16 bitsIdentifica o processo destinatário no host receptor
Número de Sequência32 bitsNúmero do primeiro byte de dados no segmento dentro do fluxo
Número de ACK32 bitsNúmero do próximo byte esperado do outro lado (ACK cumulativo)
Header Length4 bitsTamanho do cabeçalho TCP em palavras de 32 bits (mínimo 5 = 20 bytes)
Flags de Controle9 bitsURG, ACK, PSH, RST, SYN, FIN — controlam o comportamento da conexão
Janela (Window)16 bitsTamanho da janela de recepção — usado para controle de fluxo
Checksum16 bitsVerificação de integridade do segmento (cabeçalho + dados)
Ponteiro Urgente16 bitsIndica o fim dos dados urgentes (usado quando flag URG está ativa)
OpçõesVariávelCampos opcionais como MSS, Window Scaling, Timestamps

Flags de Controle

As flags de controle do TCP são bits individuais que sinalizam o tipo e o propósito do segmento:

FlagNomeFunção
SYNSynchronizeSolicita abertura de conexão — usado no handshake de 3 vias
ACKAcknowledgmentIndica que o campo Número de ACK é válido — presente em quase todos os segmentos após o handshake
FINFinishSolicita encerramento da conexão
RSTResetReseta a conexão abruptamente — indica erro ou rejeição
PSHPushSolicita que o receptor entregue os dados à aplicação imediatamente
URGUrgentIndica que o segmento contém dados urgentes — referenciados pelo Ponteiro Urgente

O cabeçalho TCP tem 20 bytes mínimos (sem opções), contra apenas 8 bytes do UDP. Esse custo extra é o preço pela confiabilidade, controle de fluxo e controle de conexão que o TCP oferece.

Números de Sequência e ACK Cumulativo

Dois dos campos mais importantes do cabeçalho TCP são o número de sequência (sequence number) e o número de reconhecimento (acknowledgment number). Eles são a base de toda a mecânica de transferência confiável do TCP.

Número de Sequência

O TCP trata os dados como um fluxo contínuo de bytes, numerados sequencialmente. O número de sequência de um segmento é o número do primeiro byte de dados contido naquele segmento dentro do fluxo.

Por exemplo, se a aplicação enviar 5000 bytes e o MSS for 1000 bytes, o TCP criará 5 segmentos:

SegmentoBytes ContidosNúmero de Sequência
Segmento 1Bytes 0–999Seq = 0
Segmento 2Bytes 1000–1999Seq = 1000
Segmento 3Bytes 2000–2999Seq = 2000
Segmento 4Bytes 3000–3999Seq = 3000
Segmento 5Bytes 4000–4999Seq = 4000

Na prática, o número de sequência inicial (ISNInitial Sequence Number) é escolhido aleatoriamente durante o handshake, não começa em zero. Isso evita conflitos com segmentos de conexões anteriores.

Número de ACK (Acknowledgment)

O número de ACK indica o próximo byte que o receptor espera receber. O TCP usa ACKs cumulativos: ao enviar ACK = N, o receptor está dizendo "recebi corretamente todos os bytes até o byte N−1 e estou esperando o byte N".

Comportamento do ACK Cumulativo

O ACK cumulativo traz uma consequência importante: se um segmento for perdido, mas segmentos posteriores chegarem, o ACK não avança além do ponto da lacuna. O receptor confirma apenas até o último byte contíguo recebido.

Evento no ReceptorAção do TCP
Segmento chega em ordem, sem lacunas, todos anteriores confirmadosACK atrasado: espera até 500ms por outro segmento. Se nenhum chegar, envia ACK
Segmento chega em ordem, sem lacunas, um ACK atrasado pendenteEnvia imediatamente um ACK cumulativo para ambos os segmentos
Segmento chega fora de ordem (seq# maior que esperado) — lacuna detectadaEnvia imediatamente um ACK duplicado com o número do byte esperado (início da lacuna)
Segmento preenche parcial ou totalmente a lacunaEnvia imediatamente um ACK se o segmento preenche o início da lacuna

O conceito de piggybacking é comum no TCP: como a conexão é full-duplex, o ACK de dados recebidos pode ser enviado junto (piggyback) com dados na direção oposta, economizando um segmento separado.

Estimativa de RTT e Timeout Adaptativo

Uma questão crucial para o TCP é: quanto tempo esperar antes de retransmitir um segmento? Se o timeout for muito curto, haverá retransmissões desnecessárias (timeouts prematuros). Se for muito longo, a recuperação de perdas será lenta.

A solução do TCP é calcular um timeout adaptativo, baseado em medições contínuas do RTT (Round-Trip Time) — o tempo entre o envio de um segmento e o recebimento de seu ACK.

Passo 1: Medir o SampleRTT

O TCP mede periodicamente o SampleRTT — o RTT real de um segmento específico (que não foi retransmitido). Essa amostra varia bastante de segmento para segmento, pois depende do congestionamento e das rotas na rede.

Passo 2: Calcular o EstimatedRTT (EWMA)

Para suavizar as flutuações, o TCP mantém uma média móvel exponencial ponderada (Exponentially Weighted Moving Average — EWMA) do RTT:

EstimatedRTT = (1 − α) × EstimatedRTT + α × SampleRTT

Onde α = 0.125 (recomendado pela RFC 6298). Isso significa que amostras recentes têm mais peso do que amostras antigas — o EstimatedRTT se adapta às mudanças na rede, mas sem reagir abruptamente a uma única amostra discrepante.

Passo 3: Calcular o DevRTT (Variabilidade)

Além da média, o TCP calcula uma estimativa da variabilidade do RTT — o DevRTT (Deviation RTT):

DevRTT = (1 − β) × DevRTT + β × |SampleRTT − EstimatedRTT|

Onde β = 0.25. O DevRTT captura o quanto o RTT real oscila em relação à média estimada.

Passo 4: Definir o TimeoutInterval

Finalmente, o timeout é calculado como:

TimeoutInterval = EstimatedRTT + 4 × DevRTT

Essa fórmula dá uma margem de segurança proporcional à variabilidade. Se o RTT é estável (DevRTT baixo), o timeout fica próximo do EstimatedRTT. Se o RTT oscila muito (DevRTT alto), o timeout é mais generoso, evitando retransmissões prematuras.

ParâmetroFórmulaValor Recomendado
EstimatedRTT(1−α) × EstimatedRTT + α × SampleRTTα = 0.125
DevRTT(1−β) × DevRTT + β × |SampleRTT − EstimatedRTT|β = 0.25
TimeoutIntervalEstimatedRTT + 4 × DevRTT
Timeout inicialValor antes da primeira medição1 segundo (RFC 6298)
Após timeoutTimeout é dobrado (backoff exponencial)Até nova medição

O TCP não mede o SampleRTT de segmentos retransmitidos (ambiguidade de Karn), pois não é possível saber se o ACK corresponde ao segmento original ou à retransmissão.

Cenários de Retransmissão

Com os mecanismos de números de sequência, ACK cumulativo e timeout adaptativo, o TCP lida com diversas situações de perda e atraso. Vamos examinar os três cenários clássicos.

Cenário 1: ACK Perdido

O Host A envia um segmento (Seq=92, 8 bytes de dados). O Host B recebe e envia ACK=100, mas o ACK é perdido na rede. O timer de A expira → A retransmite o segmento (Seq=92). B percebe que é uma duplicata (já recebeu esses bytes), descarta os dados, mas reenvia ACK=100.

Cenário 2: Timeout Prematuro

O Host A envia dois segmentos (Seq=92 e Seq=100). O timer do primeiro segmento expira antes de o ACK chegar (o ACK está a caminho, mas o timeout foi curto demais). A retransmite Seq=92. Quando os ACKs chegam (ACK=100, depois ACK=120), A percebe que os dois segmentos foram recebidos. Quando chega o ACK do segmento retransmitido (ACK=120 novamente), A simplesmente o aceita.

Cenário 3: ACK Cumulativo Salva o Dia

O Host A envia dois segmentos (Seq=92 e Seq=100). O ACK=100 do primeiro segmento é perdido, mas o ACK=120 do segundo segmento chega. Como o ACK é cumulativo, ACK=120 significa "recebi tudo até o byte 119". Portanto, A sabe que ambos os segmentos foram recebidos — nenhuma retransmissão é necessária, mesmo com o primeiro ACK perdido!

O ACK cumulativo é uma das grandes forças do TCP: mesmo que alguns ACKs se percam, basta que um ACK mais recente chegue para confirmar todos os bytes anteriores.

Resumo da Aula

Neste capítulo, exploramos os fundamentos do protocolo TCP:

  • Características gerais: TCP é ponto-a-ponto, full-duplex, orientado a conexão, com fluxo de bytes confiável e ordenado. A aplicação escreve no socket, e o TCP segmenta os dados em pedaços de até MSS bytes.
  • Estrutura do segmento: O cabeçalho TCP tem 20+ bytes, incluindo portas, número de sequência, número de ACK, flags (SYN, ACK, FIN, RST, PSH, URG), janela de recepção, checksum e opções.
  • Números de sequência: Baseados em bytes (não pacotes) — o Seq# é o número do primeiro byte de dados do segmento no fluxo.
  • ACK cumulativo: O ACK# indica o próximo byte esperado — confirma todos os bytes até aquele ponto. Se há lacunas, o ACK não avança.
  • Estimativa de RTT (EWMA): O TCP calcula uma média móvel exponencial do RTT com α = 0.125, suavizando flutuações na rede.
  • Timeout adaptativo: TimeoutInterval = EstimatedRTT + 4×DevRTT — combina a média do RTT com uma margem proporcional à variabilidade (DevRTT, β = 0.25).
  • Cenários de retransmissão: O TCP lida com ACKs perdidos, timeouts prematuros e usa o ACK cumulativo para evitar retransmissões desnecessárias.