Ключевые отличия TCP и UDP
Какие ключевые отличия TCP и UDP?
Теория: что именно отличает TCP и UDP
TCP предоставляет приложению надёжный байтовый поток «по порядку» и является протоколом с установлением соединения.
UDP предоставляет «датаграммный» режим обмена с минимумом механизмов и без гарантий доставки, защиты от дублей и упорядочивания.
Для веб-разработки это означает: выбор TCP упрощает корректность и целостность данных, а выбор UDP упрощает минимизацию задержки и даёт больше контроля приложению, но повышает ответственность за надёжность.
Ключевые свойства в таблице
| Свойство | TCP | UDP |
|---|---|---|
| Модель данных | Байтовый поток (границ сообщений нет) | Датаграммы (границы сообщений сохраняются) |
| Соединение | Есть установление соединения и состояния | Соединения на уровне протокола нет |
| Доставка | Надёжная (повторы при потерях) | Best-effort (может потеряться) |
| Порядок | Гарантирован для байтового потока | Не гарантирован |
| Дубли | Отфильтровываются механизмами TCP | Возможны, требуется дедупликация приложением |
| Контроль потока | Есть (защита получателя) | Нет (нужно делать в приложении при необходимости) |
| Контроль перегрузки | Есть (адаптация скорости) | Нет (при необходимости реализуется поверх UDP) |
| Задержка при потерях | Может расти из-за переотправок и ожидания порядка | Может быть ниже, так как можно пропускать потери |
Разбор отличий
Поток vs датаграммы (границы сообщений)
TCP:
- Передаются байты, а не сообщения.
- Одна операция записи не равна одному «получению»: данные могут прийти частями или склеенными.
UDP:
- Одна отправка соответствует одной датаграмме.
- Если датаграмма пришла, она приходит целиком (в рамках лимитов), и граница сообщения сохраняется.
Надёжность: подтверждения и повторы
TCP:
- Используются номера последовательности и подтверждения.
- Потерянные сегменты переотправляются автоматически.
UDP:
- Подтверждений и повторов нет.
- Если требуется надёжность, она проектируется на прикладном уровне: messageId, ack, timeout, retry, окно.
Порядок и «блокировка по порядку» (HOL)
TCP:
- Приложение получает байты строго по порядку.
- При потере сегмента последующие байты могут «застрять», пока не будет восстановлена «дыра» (head-of-line blocking для потока).
UDP:
- Порядок не гарантирован.
- Потеря одного сообщения не блокирует доставку других; возможно продолжение работы «как есть».
Контроль потока и перегрузки
TCP:
- Контроль потока предотвращает переполнение буфера получателя.
- Контроль перегрузки уменьшает скорость при признаках перегрузки сети, повышая устойчивость.
UDP:
- Встроенных механизмов нет.
- При массовой отправке без ограничений возможно создание перегрузки, потерь и нестабильной задержки.
Накладные расходы и «время до первого байта»
TCP:
- Требуется установление соединения (рукопожатие), что добавляет задержку перед началом передачи.
- Состояние соединения позволяет эффективно управлять передачей при длительных сессиях.
UDP:
- Можно отправлять сразу, без рукопожатия на уровне UDP.
- Для защищённых или надёжных поверхностей (например, современные транспорты поверх UDP) рукопожатие и криптография появляются уже в протоколах поверх UDP.
Схемы (упрощённо)
TCP: установление соединения (3 шага)
клиент сервер
SYN (seq=x) ----------------->
<----------------- SYN+ACK (seq=y, ack=x+1)
ACK (ack=y+1) ----------------->
(соединение установлено, можно передавать данные)
UDP: обмен без соединения
клиент сервер
DATAGRAM #1 ----------------->
DATAGRAM #2 ----------------->
(ответ может прийти, может не прийти, порядок не гарантирован)
Где это встречается в вебе
- HTTP/1.1 и HTTP/2 обычно работают поверх TCP: важна целостность данных, а повторные передачи допустимы.
- WebSocket работает поверх TCP (через HTTP Upgrade): для приложений удобен надёжный поток, но требуется учитывать, что TCP — это поток без границ сообщений.
- WebRTC чаще использует UDP: для голоса/видео важнее задержка, чем идеальная доставка каждого пакета.
- HTTP/3 работает поверх транспорта на базе UDP (через QUIC): достигаются надёжность и мультиплексирование без части ограничений классического TCP на уровне одного потока.
Примеры кода (Node.js)
TCP: сервер и клиент (важно: это поток)
TCP сервер:
const net = require('net');
const server = net.createServer((socket) => {
socket.setNoDelay(true);
socket.on('data', (chunk) => {
// chunk — произвольная порция байт: нет границ сообщений
socket.write(chunk);
});
socket.on('error', () => {});
});
server.listen(9000, '127.0.0.1');
TCP клиент:
const net = require('net');
const socket = net.connect({ host: '127.0.0.1', port: 9000 }, () => {
socket.write('hello');
socket.write('world');
});
socket.on('data', (chunk) => {
// может прийти 'helloworld', или 'hello' затем 'world', или иначе
});
Пример фрейминга «длина (uint32be) + payload»:
const net = require('net');
function encodeFrame(buf) {
const header = Buffer.alloc(4);
header.writeUInt32BE(buf.length, 0);
return Buffer.concat([header, buf]);
}
function createFrameDecoder(onFrame) {
let acc = Buffer.alloc(0);
return (chunk) => {
acc = Buffer.concat([acc, chunk]);
while (acc.length >= 4) {
const len = acc.readUInt32BE(0);
if (acc.length < 4 + len) break;
const frame = acc.slice(4, 4 + len);
acc = acc.slice(4 + len);
onFrame(frame);
}
};
}
const server = net.createServer((socket) => {
const decode = createFrameDecoder((frame) => {
socket.write(encodeFrame(frame));
});
socket.on('data', decode);
});
server.listen(9001, '127.0.0.1');
UDP: сервер и клиент (важно: это датаграммы)
UDP сервер:
const dgram = require('dgram');
const server = dgram.createSocket('udp4');
server.on('message', (msg, rinfo) => {
// msg — одна датаграмма, границы сообщения сохранены
server.send(msg, rinfo.port, rinfo.address);
});
server.bind(9002, '127.0.0.1');
UDP клиент:
const dgram = require('dgram');
const client = dgram.createSocket('udp4');
client.send(Buffer.from('ping'), 9002, '127.0.0.1');
client.on('message', (msg) => {
// доставка не гарантирована; может не прийти
});
Команды для быстрой проверки
Полезные однострочные примеры:
- Проверка TCP порта:
nc -vz 127.0.0.1 9000 - Отправка UDP датаграммы:
echo -n "ping" | nc -u -w1 127.0.0.1 9002
Кратко: TCP — это надёжный упорядоченный байтовый поток с установлением соединения, подтверждениями, повторами и встроенными механизмами контроля потока и перегрузки, что удобно для большинства веб-протоколов. UDP — это обмен датаграммами без соединения и без гарантий доставки/порядка, что снижает накладные расходы и может уменьшать задержку, но переносит ответственность за надёжность и управление скоростью на прикладной уровень, что особенно важно для real-time сценариев (например, WebRTC) и современных транспортов поверх UDP (например, HTTP/3 через QUIC).