Pular para o conteúdo principal

2026-09-02 · Atualizado em 2026-10-26

ICMP vs TCP vs UDP: a diferença, explicada para desenvolvedores

  • redes
  • icmp
  • tcp
  • udp
  • ping
  • monitoramento

Resumo

ICMP, TCP e UDP viajam todos dentro de pacotes IP, mas fazem perguntas diferentes. O echo do ICMP (ping) pergunta “este endereço responde de algum jeito?” e não precisa de porta. O TCP pergunta “tem algum programa escutando nesta porta?” e recebe um sim claro, um não claro ou silêncio. O UDP, sozinho, não pergunta nada: você só descobre alguma coisa se o programa do outro lado decidir responder. Uma porta fechada responde de um jeito diferente em cada um, e essa diferença é quase tudo o que uma verificação de rede consegue e não consegue dizer.

Um endereço, três jeitos de bater à porta

Todo pacote na internet é um pacote IP. O IP sabe levar um pacote de um endereço a outro e mais nada. Um byte no cabeçalho IP diz o que vai dentro, e a IANA mantém a lista: o ICMP é o protocolo 1, o TCP é o protocolo 6 e o UDP é o protocolo 17. Os três são irmãos: os mesmos endereços, os mesmos roteadores e uma promessa diferente sobre o que acontece quando o pacote chega.

O echo do ICMP, o handshake de três vias do TCP e o datagrama UDP desenhados como três faixas entre você e um host, cada uma terminando com o que o silêncio significa naquele protocolo.

ICMPTCPUDP
EspecificaçãoRFC 792 (1981), RFC 4443 para IPv6RFC 9293 (2022)RFC 768 (1980)
Número de protocolo IP1 (58 para ICMPv6)617
Portasnenhumaorigem e destinoorigem e destino
Handshakenenhumtrês pacotes antes de qualquer dadonenhum
Garantia de entreganenhumaem ordem, completa, com retransmissãonenhuma
Cabeçalho8 bytes para um echo20 bytes no mínimo8 bytes
Usos típicosping, traceroute, relatórios de erroHTTP/1.1 e HTTP/2, TLS, SSH, SQL, SMTPDNS, NTP, QUIC e HTTP/3, vídeo, jogos

ICMP: a rede falando de si mesma

O ICMP não é um transporte. A RFC 792 diz isso com todas as letras: o ICMP “é, na verdade, parte integrante do IP e deve ser implementado por todo módulo IP”. Ele existe para que roteadores e hosts possam relatar a entrega: este destino está inalcançável, aquele pacote esgotou os saltos. As mensagens ICMP têm um tipo e um código, mas nenhuma porta, porque não há nada acima do ICMP esperando por elas. A própria pilha IP as consome.

A mensagem ICMP que todo mundo já digitou é o echo. O ping envia um echo request (tipo 8, ou 128 no ICMPv6) e o kernel do host do outro lado devolve um echo reply (tipo 0, ou 129). Nenhum programa precisou estar rodando. A RFC 1122, o padrão de requisitos para hosts, transforma isso em regra: “Todo host DEVE implementar uma função de servidor ICMP Echo que recebe Echo Requests e envia os Echo Replies correspondentes.”

$ ping -c 1 uptimepage.dev
PING uptimepage.dev (204.168.246.94): 56 data bytes
64 bytes from 204.168.246.94: icmp_seq=0 ttl=50 time=96.069 ms

Uma resposta prova duas coisas: o endereço pertence a uma máquina ligada, e os pacotes conseguem ir até lá e voltar. De brinde, ela ainda dá o tempo de ida e volta.

É só isso que um ping prova. Ele não diz nada sobre se um servidor web, um banco de dados ou qualquer outra coisa está rodando, e um host pode responder a todo ping enquanto todos os serviços dele estão mortos.

Duas coisas sobre o ICMP pegam as pessoas de surpresa. A primeira é que ficar sem resposta não significa estar fora do ar. Firewalls descartam ICMP o tempo todo. Na AWS, um grupo de segurança recém-criado bloqueia o ICMP, e a documentação avisa: “Para fazer ping na sua instância, você precisa adicionar uma das seguintes regras ICMP de entrada.” Antes de confiar no ping para um host, confirme que esse host responde a ping.

A segunda é que enviar ICMP exige privilégio. Um raw socket precisa de CAP_NET_RAW. O Linux tem uma alternativa sem privilégio, o socket de datagrama ICMP, mas a documentação do kernel diz que o ping_group_range padrão é “1 0”, “ou seja, ninguém (nem mesmo o root) pode criar sockets de ping”. O Docker libera essa faixa em todo contêiner que ganha o próprio namespace de rede, e é por isso que o ping funciona ali sem ninguém pensar no assunto; já um contêiner com --network host herda a configuração do host. Aprendi os limites disso do jeito mais demorado: o mesmo binário de sonda que fazia ping sem problema no Docker não conseguia sequer abrir um socket ICMP numa microVM Firecracker, até eu dar a ele CAP_NET_RAW.

TCP: uma promessa antes do primeiro byte

O TCP é uma conexão. Antes que qualquer um dos lados envie um byte de dados, as duas pontas fazem o handshake de três vias: SYN, SYN-ACK, ACK. A RFC 9293, que em 2022 substituiu a especificação de 1981, o chama de “o procedimento usado para estabelecer uma conexão”. Ele custa uma ida e volta, e essa ida e volta paga todas as promessas que o TCP faz depois: os bytes chegam em ordem, os segmentos perdidos são reenviados, o receptor não é inundado (controle de fluxo) e a rede não é inundada (controle de congestionamento). Para o programa, tudo parece um fluxo contínuo. Você escreve bytes de um lado e lê os mesmos bytes, na mesma ordem, do outro.

É sobre ele que rodam HTTP/1.1, HTTP/2, TLS, SSH, PostgreSQL, MySQL, SMTP e a maior parte do que você coloca em produção.

O handshake também é uma boa sonda, porque um SYN recebe uma de três respostas:

  1. SYN-ACK. Tem um programa escutando. O connect dá certo.
  2. RST. Não tem nada escutando. A RFC 9293 diz que, se a conexão não existe, “um reset é enviado em resposta a qualquer segmento recebido, exceto outro reset”. O seu connect falha na hora com “connection refused”.
  3. Nada. Um firewall descartou o SYN, ou o host sumiu. O kernel continua tentando. No Linux, o tcp_syn_retries padrão é 6, e a documentação do kernel coloca o tempo limite final de uma tentativa de conexão ativa em 131 segundos.

Aqui estão as três, rodadas no meu notebook. A última tem um limite de três segundos; sem ele, o macOS espera 75 segundos.

$ nc -zv uptimepage.dev 443
Connection to uptimepage.dev port 443 [tcp/https] succeeded!

$ nc -zv 127.0.0.1 9
nc: connectx to 127.0.0.1 port 9 (tcp) failed: Connection refused

$ nc -zv -G 3 uptimepage.dev 8443
nc: connectx to uptimepage.dev port 8443 (tcp) failed: Operation timed out

A documentação do Nmap dá a esses estados os nomes que todo mundo usa: open, closed e filtered.

O que um handshake bem-sucedido prova: um processo aceitou uma conexão naquela porta. Não que ele esteja saudável. Um banco de dados que aceita conexões e depois rejeita todas as consultas continua passando. Por isso a verificação TCP serve para o que não tem superfície HTTP (SSH, SMTP, a porta de um banco de dados), e a verificação HTTP, para o que tem.

UDP: uma mensagem, e nada mais

O UDP é o menor transporte que existe. A RFC 768 cabe em três páginas. Ele acrescenta a um pacote IP uma porta de origem, uma porta de destino, um comprimento e um checksum, 8 bytes no total, e para por aí. A RFC diz: “O protocolo é orientado a transações, e a entrega e a proteção contra duplicatas não são garantidas.” Não há handshake, confirmação de recebimento, ordenação nem retransmissão, e também não há controle de congestionamento. A RFC 8085 começa dizendo que o UDP “não tem mecanismos inerentes de controle de congestionamento” e depois passa mais de cinquenta páginas explicando a quem projeta aplicações como adicionar os seus próprios.

Por que alguém usa UDP: latência e controle. Uma consulta DNS é um pacote de ida e um de volta, sem handshake. A RFC 1035 limitou a resposta DNS via UDP a 512 bytes. Depois, o EDNS(0) (RFC 6891) permitiu que o cliente anunciasse um buffer maior, então hoje a maioria das respostas cabe num único datagrama; uma que ainda não cabe vem truncada, com o bit TC ligado, e o cliente pergunta de novo via TCP (RFC 7766). NTP, a maior parte do tráfego de jogos e o vídeo em tempo real usam UDP porque um pacote atrasado vale menos do que o próximo, e esperar uma retransmissão é a troca errada. E o QUIC, o transporte por baixo do HTTP/3, é construído inteiramente sobre UDP. A RFC 9000 afirma que “os pacotes QUIC são transportados em datagramas UDP” e dá como motivo “facilitar a implantação em sistemas e redes existentes”. Na prática, isso significa que o QUIC faz o próprio handshake, a recuperação de perdas e o controle de congestionamento na aplicação, e pode mudá-los sem esperar que todo sistema operacional atualize a sua pilha TCP.

$ dig @1.1.1.1 uptimepage.dev A +noall +answer +stats
; <<>> DiG 9.10.6 <<>> @1.1.1.1 uptimepage.dev A +noall +answer +stats
; (1 server found)
;; global options: +cmd
uptimepage.dev.		3600	IN	A	204.168.246.94
;; Query time: 125 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Wed Sep 02 11:40:44 EEST 2026
;; MSG SIZE  rcvd: 59

Um datagrama de ida, um datagrama de volta com uma resposta de 59 bytes (67 bytes com o cabeçalho UDP), e nenhum handshake antes. Via TCP, a mesma consulta custa duas idas e voltas, uma para o handshake e outra para a consulta, e é por isso que o DNS usa UDP por padrão.

Agora, o problema da sondagem. Envie um datagrama UDP para uma porta: o que volta?

Se não há nada escutando ali, a pilha IP do host deveria responder com um erro ICMP. A RFC 1122 de novo: “Se chegar um datagrama endereçado a uma porta UDP para a qual não há uma chamada LISTEN pendente, o UDP DEVERIA enviar uma mensagem ICMP Port Unreachable.” Então “fechada” é detectável, e quem detecta é o ICMP.

Se há algo escutando, você recebe o que esse programa decidir enviar. Um servidor DNS envia uma resposta. Um receptor de syslog não envia nada, nunca. Então o silêncio quer dizer porta aberta, filtrada ou morta, e o Nmap tem um estado para isso, open|filtered. A documentação dele explica: “Isso ocorre em tipos de varredura nos quais portas abertas não dão resposta.”

A consequência é que não existe uma “verificação de porta UDP” genérica. Para verificar um serviço UDP, você precisa falar o protocolo dele: enviar uma consulta DNS de verdade e ler a resposta, enviar uma requisição NTP de verdade e conferir o timestamp. É por isso que as ferramentas de monitoramento têm verificação DNS e verificação TCP, mas raramente verificação UDP.

A mesma porta fechada, três respostas

SituaçãoEcho ICMPSYN TCPDatagrama UDP
Serviço no arecho replySYN-ACKa resposta do programa, ou nada
Porta fechada, host no arecho reply (o ICMP não tem portas)RST, “connection refused”ICMP port unreachable
Firewall descarta o pacotesilênciosilêncio, com novas tentativas por cerca de dois minutossilêncio
Host sumiusilêncio, ou um erro de destino inalcançável vindo do último roteadorsilêncio, ou esse mesmo erro ICMP aparecendo como “no route to host”silêncio, ou esse mesmo erro ICMP

Leia a tabela por colunas. O TCP é o único em que “fechada” e “filtrada” parecem diferentes por si só, o UDP pega o ICMP emprestado para dizer “fechada”, e o ICMP não enxerga porta nenhuma. O silêncio é a resposta ambígua nos três, e é por isso que nenhuma verificação deveria concluir “fora do ar” a partir de uma única sonda sem resposta, enviada de um único lugar. Duas ou três falhas consecutivas, vistas de mais de uma rede, são o critério honesto. Escrevi sobre isso em como acabar com alarmes falsos de uptime.

O que isso significa para um monitor

Eu desenvolvo o Uptimepage, e os tipos de verificação dele correspondem a essas perguntas, então é assim que a teoria vira configuração.

  • O ping envia um único echo ICMP com payload de 32 bytes, o tamanho que o ping do Windows usa (o ping do Unix envia 56, como mostra a saída acima), para que os equipamentos no meio do caminho vejam tráfego de diagnóstico comum. Ele tenta o primeiro endereço IPv4 e o primeiro IPv6 do host e divide o tempo limite entre os dois. Silêncio durante todo esse tempo conta como fora do ar, porque um echo não tem como recusar. Use para roteadores, gateways e hosts que não expõem nenhum serviço.
  • O TCP faz o handshake e fecha a conexão. Conexão aceita é no ar, recusada é fora do ar, e um estouro do tempo limite é registrado como erro, junto com o tempo que levou. Para os alertas, um erro conta como verificação com falha exatamente como fora do ar, então uma porta bloqueada por firewall ainda abre um incidente quando o limite de confirmação é atingido. Use para bancos de dados, brokers, SSH e e-mail, onde “um processo aceitou a conexão” é o máximo que dá para afirmar de fora.
  • O DNS envia uma consulta de verdade e confere o conteúdo da resposta, então ele é a verificação UDP do único serviço UDP de que quase todo mundo depende. Ele pode apontar para um resolvedor específico, o que importa quando você quer a visão daquele servidor, e não a do seu cache.
  • O HTTP é um handshake TCP, depois TLS, depois uma requisição, e registra o tempo gasto em cada fase: DNS, conexão, TLS e tempo até o primeiro byte. A fase de conexão é o handshake deste artigo, medido dentro de uma verificação maior.

Escolha a verificação que faz a pergunta que importa para você, e lembre-se do que cada uma não enxerga. Há uma versão mais completa dessa decisão na documentação dos tipos de monitor e uma versão em forma de história em o mistério do site “fora do ar”.

Perguntas frequentes

O ICMP é um protocolo de transporte como o TCP e o UDP?

Não. O ICMP é um protocolo de controle que faz parte do próprio IP, e a RFC 792 diz que todo módulo IP precisa implementá-lo. Ele não tem portas e não carrega dados de aplicação. Ele serve para relatar a entrega: um destino inalcançável, um pacote que esgotou os saltos, além do par de mensagens echo que o ping usa.

Por que o ping funciona enquanto o meu site está fora do ar?

Porque o ping só prova que a pilha IP do host responde e que os pacotes conseguem ir até lá e voltar. Quem envia o echo reply é o kernel, então nenhum servidor web, banco de dados ou outro programa precisa estar rodando. Um host pode responder a todo ping enquanto todos os serviços dele estão mortos.

Por que uma porta TCP fechada falha na hora, mas uma bloqueada por firewall fica travada?

Uma porta fechada devolve um reset TCP, então a conexão falha imediatamente com “connection refused”. Um firewall que descarta o SYN não envia nada, e o kernel continua tentando. No Linux, o padrão é de seis novas tentativas, e a documentação do kernel coloca o tempo limite final em 131 segundos.

Posso verificar uma porta UDP do mesmo jeito que verifico uma porta TCP?

Não, porque uma porta UDP aberta não devolve nada, a não ser que o programa por trás dela decida responder. Uma porta fechada é detectável, já que o host deveria responder com uma mensagem ICMP port unreachable, mas uma porta aberta e uma filtrada dão o mesmo silêncio. Para verificar um serviço UDP, você precisa falar o protocolo dele, por exemplo enviar uma consulta DNS de verdade.

Se o UDP não é confiável, por que o HTTP/3 usa UDP?

O UDP em si não dá nenhuma garantia de entrega, e o QUIC acrescenta a sua própria por cima. O QUIC roda dentro de datagramas UDP e faz o próprio handshake, a retransmissão e o controle de congestionamento na aplicação, o que permite que ele evolua sem esperar que todo sistema operacional atualize a sua pilha TCP.

Fontes

Artem Senenko

Artem Senenko

Fundador e engenheiro de software, Uptimepage

Engenheiro de software com mais de 20 anos construindo e operando sistemas em produção: arquitetura de microsserviços no Kubernetes, infraestrutura em nuvem com AWS e Terraform, e SaaS crítico para segurança no setor de fintech.

← Voltar para todas as notas