TCP и UDP: в чём разница и что на самом деле проверяет мониторинг порта
12 мин чтения
TCP и UDP: в чём разница и что на самом деле проверяет мониторинг порта

TCP и UDP: в чём разница и что на самом деле проверяет мониторинг порта

Два транспортных протокола делят между собой почти весь интернет: TCP везёт сайты, почту и базы данных, UDP — DNS, звонки, игры, VPN и HTTP/3. Разбираем, чем они отличаются на уровне заголовков и рукопожатия, какие сервисы на чём работают, почему TCP-порт проверяется одной командой, а UDP-порт извне «проверить» нельзя — и что это значит для мониторинга.

TCP (Transmission Control Protocol, RFC 9293) — транспортный протокол с установлением соединения: перед передачей данных стороны обмениваются тремя сегментами, каждый байт нумеруется, подтверждается и при потере отправляется повторно, поэтому приложение получает данные без потерь и в исходном порядке. UDP (User Datagram Protocol, RFC 768) — транспортный протокол без соединения: датаграмма уходит адресату сразу, без рукопожатия, подтверждений и повторов, и если она потерялась или пришла позже соседней, транспорт об этом не сообщит. За надёжность TCP платит минимум одним круговым обходом до первого байта данных и 20 байтами заголовка против 8 у UDP.

Чем отличается TCP от UDP: сводная таблица

Главное отличие — TCP берёт надёжность на себя, а UDP оставляет её приложению; рукопожатие, заголовок, контроль перегрузки и задержка — следствия этого выбора. Оба работают на транспортном уровне и делят одно пространство портов 0–65535 (что такое порт — в отдельной статье, место транспорта в стеке — в разборе модели OSI на примере сайта).

Критерий TCP UDP
Соединение Есть: SYN → SYN-ACK → ACK, закрытие через FIN или RST Нет: первая же датаграмма несёт данные
Гарантия доставки Да: номера последовательности, ACK, ретрансмит по таймеру (начальный RTO 1 с по RFC 6298) и по дублирующим ACK Нет: транспорт потерю не замечает
Порядок Сохраняется: приложение читает непрерывный поток байтов Не гарантируется; зато сохраняются границы сообщений
Контроль потока и перегрузки Окно приёмника (16 бит, до 65 535 байт; с масштабированием по RFC 7323 — до 1 ГиБ) плюс cwnd отправителя (CUBIC, BBR) Нет: отправитель шлёт с любой скоростью (RFC 8085 лишь рекомендует сдерживаться)
Размер заголовка 20 байт без опций, до 60 с опциями (MSS, SACK, timestamps, wscale) 8 байт: два порта, длина, контрольная сумма
Накладные расходы 3 сегмента до данных, состояние в памяти обеих сторон, ACK на каждые 1–2 сегмента Ноль служебных пакетов, состояния нет
Задержка до первого байта Минимум 1 RTT на рукопожатие (плюс 1 RTT на TLS 1.3) 0 RTT: данные в первом пакете
Типичное применение Веб (HTTP/1.1, HTTP/2), почта, SSH, базы данных, файлы DNS, NTP, DHCP, VoIP, игры, VPN, HTTP/3

Как устанавливается TCP-соединение и почему в UDP рукопожатия нет

TCP-соединение открывается тремя сегментами: клиент шлёт SYN со своим начальным номером последовательности, сервер отвечает SYN-ACK со своим номером и подтверждением клиентского, клиент завершает обмен ACK. После этого обе стороны знают, что порт слушает, а стеки договорились о номерах, MSS и масштабе окна. UDP этого не делает, потому что ему нечего согласовывать: нет номеров, окон и состояния.

Шаг TCP UDP
1 Клиент → сервер: SYN, seq=x (плюс MSS, SACK, wscale) Клиент → сервер: датаграмма с данными (DNS-запрос, 29 байт)
2 Сервер → клиент: SYN-ACK, seq=y, ack=x+1 Сервер → клиент: ответ — если приложение захотело ответить
3 Клиент → сервер: ACK, ack=y+1 — состояние ESTABLISHED —
Порт закрыт Сервер → клиент: RST (RFC 9293: reset на любой сегмент к несуществующему соединению) Ядро сервера шлёт ICMP Port Unreachable (тип 3, код 3) — если ICMP не зарезан
$ sudo tcpdump -ni eth0 'host 203.0.113.10 and (port 443 or port 53)'
# пример вывода: рукопожатие TCP — три сегмента, length 0
10:14:02.118 IP 198.51.100.7.51422 > 203.0.113.10.443: Flags [S],
    seq 1938413052, win 64240, options [mss 1460,sackOK,wscale 7], length 0
10:14:02.141 IP 203.0.113.10.443 > 198.51.100.7.51422: Flags [S.],
    seq 771302910, ack 1938413053, win 65160, options [mss 1460], length 0
10:14:02.141 IP 198.51.100.7.51422 > 203.0.113.10.443: Flags [.],
    ack 1, win 502, length 0

# пример вывода: UDP — запрос и ответ, никакого рукопожатия
10:14:05.002 IP 198.51.100.7.40321 > 203.0.113.10.53:
    41235+ A? example.com. (29)
10:14:05.019 IP 203.0.113.10.53 > 198.51.100.7.40321:
    41235 1/0/0 A 93.184.215.14 (45)

23 мс между SYN и SYN-ACK — RTT до сервера, столько TCP «теряет» перед первым байтом; HTTPS добавляет ещё RTT на TLS 1.3. QUIC (RFC 9000, май 2021) поверх UDP встраивает TLS 1.3 в свой хендшейк и укладывается в один RTT, при повторном подключении — в ноль.

Какие протоколы работают поверх TCP, а какие поверх UDP

Правило выбора: если потеря данных недопустима, а лишние 20–50 мс не критичны — TCP; если свежий пакет ценнее старого (голос, видео, игры) или обмен — один короткий запрос и ответ (DNS, NTP) — UDP. Сводка на сентябрь 2026, порты — из реестра IANA.

Протокол / сервис Транспорт Порт Примечание
HTTP/1.1 TCP 80 Один запрос за раз на соединение
HTTPS (HTTP/1.1, HTTP/2 поверх TLS) TCP 443 HTTP/2 мультиплексирует потоки в одном соединении
HTTP/3 (QUIC) UDP 443 RFC 9114; браузер узнаёт о нём из Alt-Svc или DNS-записи HTTPS
DNS UDP, fallback TCP 53 Ответ не влез — флаг TC и повтор по TCP; AXFR всегда TCP; по RFC 7766 TCP обязателен
DNS over TLS / over QUIC TCP / UDP 853 DoT — RFC 7858, DoQ — RFC 9250
NTP UDP 123 Пакет туда, пакет обратно; ретрансмит лишь исказил бы замер
DHCP UDP 67 сервер / 68 клиент Широковещание: у клиента ещё нет IP, TCP невозможен
SNMP UDP 161 / 162 трапы Опрос тысяч устройств без тысяч соединений
SIP UDP или TCP 5060 / 5061 (TLS) Сигнализация звонка; голос идёт отдельно
RTP / SRTP (голос, видео) UDP динамические, часто 10000–20000 Потерять 20 мс голоса дешевле, чем ждать повтор 200 мс
WireGuard UDP 51820 (по умолчанию) Молчит без валидного ключа — извне неотличим от закрытого порта
OpenVPN UDP (есть режим TCP) 1194 TCP-режим — обход файрволов ценой «TCP поверх TCP»
Онлайн-игры UDP свои (27015 у Source-игр) Старый пакет с координатами бесполезен
SSH / SFTP TCP 22 Терминал без потерь и порядка невозможен
SMTP TCP 25 между серверами / 587 отправка / 465 SMTPS Письмо либо доставлено целиком, либо нет
IMAP / POP3 TCP 143, 993 / 110, 995 Долгоживущие сессии с состоянием
MySQL / MariaDB TCP 3306 Локально часто unix-сокет, снаружи — только TCP
PostgreSQL TCP 5432 То же
Redis TCP 6379 Наружу не открывать: аутентификации по умолчанию нет
RDP TCP + UDP 3389 Подключение по TCP, поток экрана при возможности — по UDP

Как проверяется TCP-порт и почему UDP-порт так проверить нельзя

TCP-порт проверяется однозначно: на SYN открытый порт отвечает SYN-ACK, закрытый — RST, молчание означает файрвол с DROP. UDP-порт однозначного ответа не даёт: открытый порт на чужую нагрузку обычно молчит, закрытый отвечает ICMP Port Unreachable, но ICMP часто зарезан или ограничен по частоте — и молчание одинаково означает «открыт», «отфильтрован» и «ICMP не дошёл». Поэтому сканеры пишут для UDP open|filtered.

Отправили Что вернул хост Что это значит nc / nmap
TCP SYN SYN-ACK Порт открыт, приложение слушает succeeded / open
TCP SYN RST Хост жив, порт закрыт (никто не слушает или REJECT tcp-reset) Connection refused / closed
TCP SYN Ничего (после повторов SYN) Файрвол с DROP, нет маршрута или хост выключен timed out / filtered
UDP-датаграмма UDP-ответ Порт открыт и приложение поняло нагрузку (nmap шлёт протокольные пробы для известных портов) open
UDP-датаграмма ICMP тип 3, код 3 Хост жив, на порту никто не слушает closed
UDP-датаграмма ICMP тип 3, код 1, 2, 9, 10 или 13 Отфильтровано файрволом или маршрутизатором filtered
UDP-датаграмма Ничего Открыт, но приложение молчит на чужую нагрузку; или DROP; или ICMP не дошёл (Linux отдаёт unreachable не чаще раза в секунду) nc: succeeded (!) / nmap: open|filtered

Отсюда частое заблуждение: nc -zvu пишет «succeeded», и это принимают за доказательство, хотя man-страница OpenBSD-netcat говорит прямо: сканирование с флагами -uz всегда сообщает об успехе независимо от состояния цели. Инструменты для TCP разобраны в статье «Как проверить, открыт ли порт»; ниже — минимум, показывающий разницу.

# TCP: три исхода различимы за одну команду
$ nc -zv -w 3 192.0.2.1 443
Connection to 192.0.2.1 443 port [tcp/https] succeeded!

$ nc -zv -w 3 192.0.2.1 8443
nc: connect to 192.0.2.1 port 8443 (tcp) failed: Connection refused

$ nc -zv -w 3 192.0.2.1 25
nc: connect to 192.0.2.1 port 25 (tcp) timed out: Operation now in progress

# UDP: «succeeded» и для DNS, и для порта, где ничего нет
$ nc -zvu -w 3 192.0.2.1 53
Connection to 192.0.2.1 53 port [udp/domain] succeeded!

$ nc -zvu -w 3 192.0.2.1 5353
Connection to 192.0.2.1 5353 port [udp/mdns] succeeded!

nmap с ключом -sU честнее: ждёт ICMP, повторяет пробы, а для известных портов (53, 123, 161 и других) отправляет осмысленную нагрузку, чтобы получить настоящий ответ приложения. Плата — время: из-за лимита ICMP в Linux полный скан 65 536 UDP-портов, по документации nmap, занимает больше 18 часов.

$ sudo nmap -sU -p 53,123,161,500,5353 192.0.2.1
# пример вывода
Starting Nmap 7.95 at 2026-09-25 10:20 MSK
Nmap scan report for 192.0.2.1

PORT     STATE         SERVICE
53/udp   open          domain
123/udp  open|filtered ntp
161/udp  open|filtered snmp
500/udp  closed        isakmp
5353/udp closed        zeroconf

Nmap done: 1 IP address (1 host up) scanned in 4.87 seconds

Достоверно UDP-порт виден только на самом сервере: ss -ulnp показывает UDP-сокеты в состоянии UNCONN (LISTEN у UDP нет, потому что нет соединения) и процесс, который их держит; -tlnp — TCP-сокеты в LISTEN.

$ sudo ss -ulnp
# пример вывода
State  Recv-Q Send-Q Local:Port    Peer:Port Process
UNCONN 0     0     0.0.0.0:53    0.0.0.0:* users:(("named",pid=812,fd=20))
UNCONN 0     0     0.0.0.0:123   0.0.0.0:* users:(("chronyd",pid=644,fd=6))
UNCONN 0     0     0.0.0.0:51820 0.0.0.0:*
# у порта 51820 нет процесса: WireGuard живёт в ядре

$ sudo ss -tlnp | grep -E ':(53|5432) '
LISTEN 0 10   0.0.0.0:53    0.0.0.0:*  users:(("named",pid=812,fd=21))
LISTEN 0 4096 0.0.0.0:5432  0.0.0.0:*  users:(("postgres",pid=1043,fd=6))

Типичные проблемы с UDP: файрвол, NAT, фрагментация и QUIC

Большинство «странных» проблем с UDP сводится к четырём: файрвол пропускает TCP, но режет UDP; NAT забывает UDP-сессию раньше, чем TCP; большой UDP-ответ фрагментируется и теряется; QUIC блокируется, и браузер тихо откатывается на TCP. Общее одно: на сервере ничего не сломано, ss показывает сокет, а извне сервис то работает, то нет.

Проблема Симптом Как проверить Как исправить
Файрвол пропускает tcp/53, режет udp/53 dig висит до таймаута, dig +tcp отвечает мгновенно; nc -zv 53 при этом «succeeded» dig @сервер example.com против dig +tcp @сервер example.com Открыть udp/53 наряду с tcp/53: в iptables/nftables это два разных правила
NAT-таймаут UDP короче TCP VPN или звонок «замирает» после паузы в 30–120 с, потом оживает Linux conntrack по умолчанию: UDP 30 с (120 с для двунаправленного потока), TCP established — 5 суток Keepalive короче таймаута: у WireGuard PersistentKeepalive = 25
Фрагментация больших DNS-ответов Короткие ответы приходят, DNSSEC-домены и длинные TXT — нет; SERVFAIL или таймауты dig +bufsize=1232 против dig +bufsize=4096; смотреть флаг tc EDNS buffer 1232 (DNS Flag Day 2020) и открытый tcp/53 для fallback
QUIC заблокирован (udp/443) Сайт открывается, но первый заход медленнее; в DevTools протокол h2 вместо h3; изредка ERR_QUIC_PROTOCOL_ERROR Столбец Protocol во вкладке Network; curl --http3-only -I Открыть udp/443 в обе стороны или осознанно выключить h3 и Alt-Svc на сервере

DNS показателен: RFC 1035 ограничил UDP-ответ 512 байтами, EDNS0 разрешил больше, но ответ на 4 КБ разбивается на IP-фрагменты, которые файрволы часто отбрасывают. Поэтому с 1 октября 2020 года (DNS Flag Day) серверы договорились о буфере 1232 байта — MTU 1280 по требованию IPv6 минус 48 байт заголовков. Что не влезло, уходит с флагом TC, и клиент переспрашивает по TCP; если tcp/53 закрыт, домен резолвится «через раз».

# UDP-запрос: ответ обрезан, стоит флаг tc — резолвер повторит по TCP
$ dig +noall +comments +bufsize=512 @192.0.2.1 example.com DNSKEY
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5211
;; flags: qr tc rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

# Тот же запрос по TCP: ответ целиком
$ dig +noall +comments +tcp @192.0.2.1 example.com DNSKEY
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

# Если tcp/53 закрыт файрволом — вот что увидит резолвер
$ dig +tcp @192.0.2.1 example.com DNSKEY
;; communications error to 192.0.2.1#53: connection refused

С QUIC откат почти незаметен: при неудаче QUIC-хендшейка Chromium помечает h3 для хоста как неработающий и ходит по TCP, пользователь платит лишним RTT на первом заходе. Если браузер всё же показывает ERR_QUIC_PROTOCOL_ERROR — это тема отдельной статьи.

Что проверяет мониторинг порта и как контролировать UDP-службы

Проверка «Порт» в мониторинге — это TCP-подключение: SYN, ожидание SYN-ACK, закрытие. Она отвечает на один вопрос — принимает ли хост соединения на этом порту — и подходит для SSH, SMTP, MySQL, PostgreSQL или порта своего приложения. Аналогичной проверки для UDP не существует: отсутствие ICMP unreachable ничего не доказывает. В Пруфене проверка порта устанавливает TCP-соединение с заданным портом из 20 точек мониторинга — 17 в России, а также Минск, Астана и Испания — с интервалом от 2 минут. Инцидент открывается, когда подключение не проходит с заданной доли точек: так отсеиваются сбои сети одной площадки. UDP-порты эта проверка не тестирует — и не делает вид, что тестирует.

UDP-службы контролируют на прикладном уровне: задают сервису настоящий вопрос и сверяют ответ. Для DNS это проверка DNS: она делает реальный запрос записей домена, и если udp/53 закрыт или сервер отдаёт не то, проверка это увидит — в отличие от порт-скана, которому UDP 53 всегда покажется «открытым». Тот же принцип для любого UDP-сервиса: NTP проверяют запросом времени, VPN — установлением туннеля, а не тем, что порт не ответил ICMP.

Порт и DNS в одной проверке

Пруфен объединяет в одной проверке несколько типов: TCP-порт для базы и SSH, HTTP для сайта, DNS для домена. Уведомление приходит в Email, Telegram или Макс, когда проверка перестала проходить, и второе — когда восстановилась; если ресурс так и не поднялся, подключается голосовой звонок. Время обнаружения равно интервалу проверки. Бесплатный план включает 5 проверок, при регистрации на баланс начисляется 150 ₽.

Частые вопросы

Почему DNS работает на UDP, а не на TCP?

Типичный обмен — запрос на 30–50 байт и ответ до нескольких сотен. По TCP это стоило бы рукопожатия, закрытия и состояния на сервере под каждого из миллионов клиентов; по UDP — ровно два пакета, а потерю резолвер лечит повтором сам. TCP при этом обязателен по RFC 7766: на него переходят при усечённом ответе (флаг TC) и для трансфера зон.

UDP действительно быстрее TCP?

Быстрее до первого байта: нет рукопожатия — минус один RTT, и нет остановок на ретрансмит. По пропускной способности на чистом канале разницы почти нет: 12 байт разницы в заголовке при кадре 1500 байт — меньше 1 %. Зато UDP-приложение без своего контроля перегрузки при потерях может забить канал себе и соседям — поэтому QUIC реализует его поверх UDP заново (RFC 9002).

Можно ли достоверно проверить UDP-порт извне?

Только зная протокол: отправить запрос, на который сервис обязан ответить, — DNS-запрос на 53, NTP-запрос на 123, SNMP GET на 161 с правильным community. Ответ пришёл — порт открыт; не пришёл — неизвестно. Универсальной пустой пробы, как SYN для TCP, у UDP нет. Для WireGuard, который молчит на всё без валидного ключа, извне не доказать даже факт существования сервиса.

HTTP/3 — это UDP? Значит, сайт может терять данные?

HTTP/3 работает поверх QUIC, а QUIC — поверх UDP, но надёжность не теряется: QUIC сам нумерует пакеты, подтверждает, повторяет потерянные и управляет перегрузкой — делает поверх UDP всё, что TCP делает в ядре. Выигрыш — один RTT на защищённое соединение вместо двух, и потеря пакета тормозит один поток, а не всю страницу. Данные доходят целиком и в порядке.

Была ли статья полезна?

Начните мониторинг прямо сейчас

Бесплатный тариф — до 5 проверок. 150 ₽ на баланс при регистрации.

Создать аккаунт