📡 Aula 04 — Camada de Transporte (TCP vs. UDP), Controle de Fluxo e Sockets de Comunicação

Navegação Rápida


📌 Sumário da Aula

  1. 🧠 1. Serviços e Propósito da Camada de Transporte
  2. 🚪 2. Multiplexação e Demultiplexação por Portas Lógicas
  3. ⚡ 3. O Protocolo UDP: Leveza e Tempo Real
  4. 🤝 4. O Protocolo TCP: Three-Way Handshake e Confiabilidade
  5. 📈 5. Controle de Fluxo (Janela Deslizante) e Congestionamento (AIMD)
  6. 💻 6. Programação com a API de Sockets Berkeley em C
  7. 📊 7. Diagrama de Transporte, Handshake e Controle de Janela
  8. 📝 8. Questões de Concursos e Problemas Avançados Resolvidos
  9. 🔗 9. Conexões e Referências Cruzadas

🧠 1. Serviços e Propósito da Camada de Transporte

Enquanto a Camada de Rede (IP) é responsável pela comunicação lógica entre estações hospedeiras (Host-to-Host), a Camada de Transporte (Camada 4 do modelo OSI e da pilha TCP/IP) provê a comunicação lógica direta entre processos ou aplicativos em execução (Process-to-Process).

Em uma mesma subestação elétrica, um único servidor de gateway com um único endereço IP pode estar executando simultaneamente:

  • Um serviço de supervisão SCADA mestre consultando registradores Modbus/TCP;
  • Um cliente de sincronismo de relógio atômico por satélite via protocolo NTP;
  • Um terminal de gerência remota segura via SSH;
  • Uma sessão de transferência de arquivos de oscilografia COMTRADE via FTP/SFTP.

A camada de transporte é a responsável por direcionar cada segmento de dados recebido da rede para o processo correto na memória do computador, sem interferências mútuas.


🚪 2. Multiplexação e Demultiplexação por Portas Lógicas

O mecanismo fundamental da camada de transporte baseia-se no conceito de Porta Lógica (Port Number), um número inteiro não assinado de 16 bits variando de a .

Uma conexão de transporte fim-a-fim na Internet é identificada de forma única por uma Quádrupla de Socket:

flowchart TD
    subgraph HostA["Servidor SCADA (IP: 10.0.0.10)"]
        Proc1["Processo Modbus Mestre (Porta Efêmera: 49500)"]
        Proc2["Processo Cliente NTP (Porta Efêmera: 51200)"]
        Proc3["Processo Terminal SSH (Porta Efêmera: 53100)"]
    end

    subgraph HostB["Relé IED / Gateway (IP: 10.0.0.50)"]
        PortModbus["Porta Bem Conhecida 502: Modbus/TCP"]
        PortNTP["Porta Bem Conhecida 123: NTP Server"]
        PortSSH["Porta Bem Conhecida 22: Servidor SSH"]
    end

    Proc1 <==>|Conexão TCP (49500 -> 502)| PortModbus
    Proc2 <==>|Datagramas UDP (51200 -> 123)| PortNTP
    Proc3 <==>|Conexão TCP (53100 -> 22)| PortSSH

Classificação Oficial de Faixas de Portas (IANA):

  1. Portas Bem Conhecidas (Well-Known Ports - a ): Reservadas para protocolos e serviços universais padronizados;
  2. Portas Registradas (Registered Ports - a ): Registradas por empresas e organizações para protocolos específicos da indústria;
  3. Portas Dinâmicas / Efêmeras (Ephemeral Ports - a ): Atribuídas temporariamente pelo sistema operacional aos clientes no momento em que iniciam uma conexão de saída.

Portas Padronizadas no Setor Elétrico:

  • Porta TCP 502: Protocolo Modbus/TCP;
  • Porta TCP/UDP 20000: Protocolo DNP3 (Distributed Network Protocol);
  • Porta TCP 2404: Protocolo IEC 60870-5-104 (Telecontrole de Sistemas de Potência);
  • Porta TCP 102: Protocolo IEC 61850 MMS (Manufacturing Message Specification);
  • Porta UDP 123: Protocolo NTP/SNTP (Sincronismo de tempo de relógios de relés);
  • Porta UDP 53: Serviço de Nomes de Domínio (DNS).

⚡ 3. O Protocolo UDP: Leveza e Tempo Real

O UDP (User Datagram Protocol, formalizado na RFC 768) é um protocolo de transporte minimalista, sem conexão (connectionless), sem garantia de entrega e sem controle de fluxo ou congestionamento.

O cabeçalho UDP possui tamanho fixo de apenas :

Campo do Cabeçalho UDPTamanhoFunção
Porta de Origem16 bits (2 B)Porta do aplicativo remetente
Porta de Destino16 bits (2 B)Porta do serviço receptor
Comprimento Total (Length)16 bits (2 B)Comprimento do cabeçalho + carga útil (em bytes)
Checksum16 bits (2 B)Verificação de integridade contra corrupção de bits

Vantagens do UDP na Engenharia:

  1. Zero Sobrecarga de Conexão: Não requer handshake inicial prévio para iniciar a transmissão. Os dados são despachados no primeiro nanossegundo;
  2. Determinismo Temporal e Jitter Mínimo: Não realiza retransmissões automáticas em caso de perda de pacotes. Se uma amostra de telemetria sofrer ruído e se perder, o sistema descarta e aguarda a próxima amostra atualizada, sem travar o processamento;
  3. Suporte Nativo a Multicast e Broadcast: Permite que um único servidor envie pacotes de sincronismo de tempo para dezenas de IEDs simultaneamente.

🤝 4. O Protocolo TCP: Three-Way Handshake e Confiabilidade

O TCP (Transmission Control Protocol, RFC 793) provê um serviço de entrega confiável, orientado à conexão, baseado em fluxo contínuo de bytes (byte-stream), com recuperação automática de perdas e garantia rigorosa de ordenação.

O cabeçalho TCP padrão possui básicos:

  • Número de Sequência (32 bits): Numera cada byte individual transmitido no fluxo;
  • Número de Confirmação / ACK (32 bits): Indica o próximo byte que o receptor espera receber (ACK acumulativo);
  • Flags de Controle (6 bits fundamentais):
    • SYN : Sincronização inicial de números de sequência;
    • ACK : Indica que o campo Número de Confirmação é válido;
    • FIN : Solicita o encerramento gracioso da conexão;
    • RST : Reset abrupto de conexão (rejeição de porta fechada ou erro fatal);
    • PSH : Força a entrega imediata dos dados ao aplicativo receptor sem esperar o buffer encher;
    • URG : Dados urgentes.

4.1 O Estabelecimento de Conexão em Três Vias (Three-Way Handshake)

Para abrir uma sessão segura entre o SCADA e o relé IED, as duas pontas devem sincronizar seus números de sequência iniciais (ISN):

sequenceDiagram
    autonumber
    participant Cliente as Mestre SCADA (Cliente)
    participant Servidor as Relé IED (Servidor)

    Note over Servidor: Servidor escutando na porta 502 (LISTEN)
    Cliente->>Servidor: 1. SYN (Seq = x) [Estado: SYN_SENT]
    Note over Servidor: Servidor aloca buffers [Estado: SYN_RCVD]
    Servidor->>Cliente: 2. SYN-ACK (Seq = y, Ack = x + 1)
    Note over Cliente: Cliente aloca buffers [Estado: ESTABLISHED]
    Cliente->>Servidor: 3. ACK (Seq = x + 1, Ack = y + 1)
    Note over Servidor: Conexão Estabelecida! [Estado: ESTABLISHED]

Somente após a conclusão do terceiro passo do aperto de mão é que dados úteis de aplicação (como comandos Modbus de abertura de disjuntor) começam a trafegar no enlace.


📈 5. Controle de Fluxo (Janela Deslizante) e Congestionamento (AIMD)

O TCP implementa dois mecanismos distintos de controle de taxa de transmissão, frequentemente confundidos na literatura:

flowchart TD
    TCP_Rate["Taxa Máxima de Transmissão TCP:<br/>Max_In_Flight = min(rwnd, cwnd)"] --> CF["1. Controle de Fluxo (Flow Control):<br/>Protege o RECEPTOR contra transbordamento de buffer.<br/>Governada pelo campo 'rwnd' anunciado no cabeçalho."]
    TCP_Rate --> CC["2. Controle de Congestionamento (Congestion Control):<br/>Protege a REDE intermediária contra colapso de roteadores.<br/>Governada pela variável interna 'cwnd' do transmissor."]

5.1 Controle de Fluxo por Janela Deslizante (Flow Control)

O receptor monitora continuamente o espaço disponível em sua memória RAM no buffer de recepção (RcvBuffer):

O receptor anuncia esse valor (Receive Window) no cabeçalho de cada pacote ACK enviado de volta. O transmissor tem a garantia matemática de que:

Se o processador do relé IED estiver sobrecarregado calculando faltas e o aplicativo parar de ler o buffer, ele envia um anúncio com (Janela Zero). O mestre SCADA suspende imediatamente a transmissão, prevenindo qualquer perda de dados por estouro de memória no IED.

5.2 Controle de Congestionamento (AIMD - Additive Increase Multiplicative Decrease)

A variável interna da janela de congestionamento () adapta-se dinamicamente às condições da rede através de três fases clássicas:

  1. Partida Lenta (Slow Start): inicia em (Maximum Segment Size) e dobra a cada RTT (crescimento exponencial: );
  2. Evitação de Congestionamento (Congestion Avoidance): Ao cruzar o limiar de transição (Slow Start Threshold), o crescimento torna-se linear: soma-se a cada RTT decorrido (Additive Increase);
  3. Detecção de Perda:
    • Se ocorrer um Timeout de temporizador: o TCP presume congestionamento severo na rota, reduz e reinicia ;
    • Se receber 3 ACKs Duplicados (Fast Retransmit): retransmite o segmento faltoso imediatamente sem aguardar o timeout e reduz pela metade (Multiplicative Decrease), prosseguindo com o crescimento linear (Fast Recovery).

💻 6. Programação com a API de Sockets Berkeley em C

A API de Sockets Berkeley é a interface padronizada POSIX adotada em sistemas operacionais Unix, Linux e sistemas embarcados de tempo real para comunicação em rede.

6.1 Implementação de um Cliente TCP Industrial em C

O código a seguir exemplifica um mestre SCADA em C99 conectando-se a um relé IED na porta Modbus/TCP 502:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
 
int main(void) {
    // 1. Criação do Socket TCP IPv4
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("Erro ao criar socket");
        return EXIT_FAILURE;
    }
 
    // 2. Configuração do Endereço de Destino (Relé IED)
    struct sockaddr_in servidor_ied;
    memset(&servidor_ied, 0, sizeof(servidor_ied));
    servidor_ied.sin_family = AF_INET;
    servidor_ied.sin_port = htons(502); // Converte para Network Byte Order (Big-Endian)
    inet_pton(AF_INET, "192.168.10.50", &servidor_ied.sin_addr);
 
    // 3. Conexão TCP (Dispara o 3-Way Handshake)
    if (connect(sockfd, (struct sockaddr *)&servidor_ied, sizeof(servidor_ied)) < 0) {
        perror("Falha na conexão com o IED");
        close(sockfd);
        return EXIT_FAILURE;
    }
    printf("Conexão estabelecida com sucesso com o IED!\n");
 
    // 4. Montagem e Envio da Mensagem Modbus/TCP
    uint8_t comando_modbus[] = {
        0x00, 0x01, // Transaction ID
        0x00, 0x00, // Protocol ID (0 = Modbus)
        0x00, 0x06, // Comprimento (6 bytes a seguir)
        0x01,       // Unit ID
        0x03,       // Função 03: Read Holding Registers
        0x00, 0x64, // Endereço inicial do registrador (100 decimal)
        0x00, 0x02  // Quantidade de registradores (2 registradores)
    };
    send(sockfd, comando_modbus, sizeof(comando_modbus), 0);
 
    // 5. Recepção da Resposta com Telemetria Fasorial
    uint8_t buffer_resposta[256];
    ssize_t bytes_lidos = recv(sockfd, buffer_resposta, sizeof(buffer_resposta), 0);
    if (bytes_lidos > 0) {
        printf("Recebidos %zd bytes de telemetria da subestação.\n", bytes_lidos);
    }
 
    // 6. Encerramento gracioso (FIN/ACK)
    close(sockfd);
    return EXIT_SUCCESS;
}

📊 7. Diagrama de Transporte, Handshake e Controle de Janela

O diagrama abaixo ilustra o fluxo completo do aperto de mão em três vias, as diferenças estruturais entre TCP e UDP, e a dinâmica da janela deslizante:


📝 8. Questões de Concursos e Problemas Avançados Resolvidos

Questão 1 (Banca CESPE/CEBRASPE - Analista de Redes e Infraestrutura de Energia)

Considere o processo de estabelecimento de uma conexão TCP entre uma estação de supervisão SCADA (cliente) e uma unidade terminal remota UTR (servidor). Durante o procedimento de Three-Way Handshake:

  1. O cliente envia um segmento contendo a flag SYN = 1, ACK = 0 e o Número de Sequência Inicial ;
  2. O servidor aceita a conexão e responde com um segmento contendo as flags SYN = 1, ACK = 1, com seu Número de Sequência Inicial próprio .

Quais devem ser os valores exatos dos campos Número de Sequência (Seq Number) e Número de Confirmação (Ack Number) no terceiro segmento enviado pelo cliente de volta ao servidor para concluir o estabelecimento da conexão?

Resolução Passo a Passo:

  1. Análise do Segmento 1 (SYN do Cliente):
    • Cliente avisa: meu primeiro byte será . O pacote SYN consome logicamente 1 número de sequência.
  2. Análise do Segmento 2 (SYN-ACK do Servidor):
    • Servidor confirma: recebi o SYN do cliente e aguardo o próximo byte:
    • Servidor avisa: meu primeiro byte será . O SYN do servidor também consome logicamente 1 número de sequência.
  3. Montagem do Segmento 3 (ACK Final do Cliente):
    • O número de sequência deste segmento deve ser o byte anunciado anteriormente:
    • O número de confirmação deve reconhecer o SYN do servidor, apontando para o próximo byte esperado:
    • As flags deste segmento são: SYN = 0, ACK = 1.


Questão 2 (Banca VUNESP - Engenheiro Eletricista / Concurso de Metrô)

Um sistema de telemetria industrial transmite pacotes de medição de grandezas de potência através do protocolo TCP. O enlace possui uma taxa de transmissão nominal de e um tempo de ida e volta (Round-Trip Time - RTT) de . Sabendo que o algoritmo de controle de fluxo opera com uma janela de recepção anunciada fixa de () e que a rede intermediária não apresenta perdas de pacotes ():

  1. Calcule a taxa máxima teórica sustentada de transferência de dados alcançável por essa conexão TCP em .
  2. Determine se a largura de banda do enlace () está sendo plenamente aproveitada.
  3. Qual deveria ser o tamanho mínimo da janela em kibibytes para saturar completamente os do canal?

Resolução Passo a Passo:

  1. Cálculo da Taxa Máxima de Transferência Limitada pela Janela: A taxa de transferência contínua máxima permitida pela janela deslizante em um canal com retardo RTT é dada pela fórmula do Produto Banda-Retardo (Bandwidth-Delay Product): Convertendo a janela de para bits: O RTT é .

  2. Avaliação do Aproveitamento da Banda: A vazão real é de apenas , o que representa apenas: A capacidade do canal está subutilizada em mais de , pois o transmissor esgota os 64 KiB e é forçado a parar de transmitir enquanto aguarda o ACK retornar.

  3. Cálculo da Janela Ótima para Saturação do Enlace (): Convertendo para bytes: Convertendo para Kibibytes ():

Conclusão de Engenharia: Para enlaces de alta velocidade e alta latência (Long Fat Networks - LFN), deve-se habilitar a opção TCP Window Scale (RFC 7323), que permite expandir o campo de janela de 16 bits para até , superando o teto histórico de .


Questão 3 (Problema Prático de Programação - Função htons e Ordem de Bytes)

Em um programa mestre em C99 para telemetria DNP3, um engenheiro define a porta de destino como a porta registrada DNP3 ( decimal). Por que é mandatório aplicar a macro htons(20000) antes de gravar o valor na estrutura sockaddr_in em um computador com processador Intel x86_64? O que ocorreria se essa conversão fosse omitida?

Resolução e Análise Crítica:

  1. Diferença de Arquitetura de Endianness:
    • A arquitetura x86_64 (e a maioria dos processadores modernos de uso geral) utiliza a convenção Little-Endian: o byte menos significativo (LSB) é armazenado no endereço de memória mais baixo;
    • Os protocolos da pilha TCP/IP padronizam universalmente a convenção Big-Endian como a Ordem de Bytes da Rede (Network Byte Order): o byte mais significativo (MSB) deve ser transmitido primeiro.
  2. Cálculo Hexadecimal: O valor decimal em hexadecimal de 16 bits é:
    • Na memória Little-Endian da máquina: os bytes residem fisicamente como [0x20, 0x4E].
  3. Efeito da Omissão do htons (Host-to-Network Short): Se o programador gravar o valor diretamente sem htons, a pilha de rede transmitirá os bytes na ordem da memória local (0x204E). No lado receptor, o servidor interpretará a porta como: O pacote será enviado para a Porta 8270 em vez da Porta 20000. O IED de destino rejeitará a conexão imediatamente com um pacote TCP RST, pois a porta 8270 estará fechada. A função htons(0x4E20) inverte a ordem dos bytes para 0x204E na memória antes do envio, garantindo que o número trafegue como 0x4E20 no cabeçalho do segmento.

🔗 9. Conexões e Referências Cruzadas

Disciplinas Vinculadas:

Materiais Didáticos Oficiais da Disciplina:

  • Arquivo de Curso: 03 - Camadas de Aplicação e Transporte (crédito Digital).pdf
  • Arquivo de Apoio: 01.2 Resolução de Problemas.pdf