← Назад к вопросам

В чём разница между TCP и UDP?

1.0 Junior🔥 161 комментариев
#Сети и протоколы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между TCP и UDP

Это два основных протокола транспортного уровня (Layer 4 в модели OSI), которые сильно отличаются друг от друга по подходу и применению. Выбор между ними критичен при проектировании сетевых приложений.

TCP (Transmission Control Protocol)

TCP — это протокол, ориентированный на соединение. Он гарантирует надёжную доставку данных в правильном порядке.

Ключевые характеристики:

  • Надёжность: Все пакеты гарантированно доставятся
  • Упорядоченность: Данные приходят в том же порядке, в котором отправлены
  • Потокоориентированность: Данные — это непрерывный поток
  • Управление потоком: Адаптивная скорость передачи
  • Трёхэтапное рукопожатие (handshake): SYN, SYN-ACK, ACK
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <iostream>

int main() {
    // Создание TCP сокета
    int serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
    // Привязка к порту
    sockaddr_in addr = {};
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    addr.sin_addr.s_addr = INADDR_ANY;
    
    bind(serverSocket, (sockaddr*)&addr, sizeof(addr));
    listen(serverSocket, 5);
    
    // Ждём входящего соединения
    int clientSocket = accept(serverSocket, nullptr, nullptr);
    
    // Отправляем данные
    const char* message = "Hello from TCP";
    send(clientSocket, message, strlen(message), 0);
    
    close(clientSocket);
    close(serverSocket);
    return 0;
}

UDP (User Datagram Protocol)

UDP — это протокол без соединения, ориентированный на дейтаграммы. Он не гарантирует доставку, но очень быстрый.

Ключевые характеристики:

  • Без соединения: Нет установления соединения
  • Ненадёжность: Пакеты могут быть потеряны
  • Неупорядоченность: Пакеты могут прийти в другом порядке
  • Дейтаграммы: Данные передаются отдельными пакетами
  • Низкая задержка: Минимальный overhead
  • Широковещание/Мультикаст: Возможна отправка многим получателям
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <iostream>
#include <cstring>

int main() {
    // Создание UDP сокета
    int serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    
    // Привязка к порту
    sockaddr_in addr = {};
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    addr.sin_addr.s_addr = INADDR_ANY;
    
    bind(serverSocket, (sockaddr*)&addr, sizeof(addr));
    
    // Получение данных
    char buffer[1024];
    sockaddr_in clientAddr;
    socklen_t clientAddrLen = sizeof(clientAddr);
    
    int bytesReceived = recvfrom(serverSocket, buffer, sizeof(buffer), 0,
                                  (sockaddr*)&clientAddr, &clientAddrLen);
    
    // Отправка ответа
    const char* response = "Received";
    sendto(serverSocket, response, strlen(response), 0,
           (sockaddr*)&clientAddr, clientAddrLen);
    
    close(serverSocket);
    return 0;
}

Таблица сравнения

АспектTCPUDP
СоединениеТребует установленияБез соединения
НадёжностьГарантированаНе гарантирована
ПорядокСохраняетсяМожет быть нарушен
СкоростьМедленнееБыстрее
OverheadВысокийНизкий
ЗадержкаВышеНиже
МасштабируемостьСложнее (per-connection state)Проще
Типичное использованиеФайлы, веб, emailВидео, звук, игры
Получение ACKДаНет
Размер пакетаДинамическийФиксированный (дейтаграмма)

Процесс установления соединения

TCP Handshake (3-way handshake)

Клиент                      Сервер
  |                            |
  |-------- SYN -------->      |
  |                   (Seq=x)  |
  |      <------ SYN-ACK ------|
  |                 (Seq=y, Ack=x+1)  |
  |-------- ACK -------->      |
  |              (Seq=x+1, Ack=y+1)  |
  |                            |
  Соединение установлено

UDP (без handshake)

Клиент                      Сервер
  |                            |
  |-------- Дейтаграмма ---->  |
  |                            |
  Сразу готов отправить       Может получить ответ

Практические примеры применения

TCP использован для

// Веб-браузер (HTTP)
std::cout << "GET /index.html HTTP/1.1\r\n";
std::cout << "Host: example.com\r\n\r\n";

// FTP (передача файлов)
// Нужно убедиться, что файл передан полностью

// Email (SMTP, IMAP, POP3)
// Критично, чтобы письмо не потеряться

// SSH (удалённое управление)
// Нужна последовательность команд

// Database connections
// ACID требует надёжности

UDP использован для

// DNS (Domain Name System)
// Быстрый запрос-ответ, если потеря — повтор клиентом

// Online видеотрансляция
// Несколько потерянных пакетов не критичны для качества

// Онлайн игры
// Быстрота важнее надёжности каждого пакета

// VoIP (голосовые звонки)
// Низкая задержка критична, потеря нескольких пакетов приемлема

// NTP (синхронизация времени)
// Простой запрос-ответ

// SNMP (мониторинг сетей)
// Периодические сообщения мониторинга

Надёжность в UDP

Если нужна надёжность с низкой задержкой UDP, приходится реализовывать самостоятельно:

struct UDPReliable {
    // Отправка с гарантией доставки
    void sendReliable(const std::string& data) {
        uint32_t sequence = ++seqNumber;
        
        // Отправляем с номером последовательности
        PacketHeader header = {sequence, data.length()};
        sendto(socket, &header, sizeof(header), 0, &remoteAddr, len);
        
        // Ждём ACK
        auto start = std::chrono::now();
        while (!receivedAck[sequence]) {
            if (timeouted(start)) {
                // Переотправляем
                sendto(socket, &header, sizeof(header), 0, &remoteAddr, len);
                start = std::chrono::now();
            }
        }
    }
    
private:
    std::map<uint32_t, bool> receivedAck;
    uint32_t seqNumber = 0;
};

Гибридный подход

Модерные приложения часто используют гибридный подход:

// QUIC (Quick UDP Internet Connections) — надёжный UDP
// Сочетает скорость UDP с надёжностью TCP
// Используется в HTTP/3

// WebRTC — UDP с собственным управлением надёжностью
// Для видеоконференций нужна скорость и некоторая надёжность

Best Practices

1. Используйте TCP если:

  • Нужна гарантия доставки (файлы, деньги, данные)
  • Важен порядок данных
  • Клиентов немного (per-connection state OK)

2. Используйте UDP если:

  • Скорость критична
  • Потеря нескольких пакетов приемлема
  • Много одновременных отправителей (streaming, broadcast)

3. Тестируйте оба протокола:

// Оба должны быть доступны для сравнения
class NetworkServer {
public:
    void startTCP(int port) { /* ... */ }
    void startUDP(int port) { /* ... */ }
};

Резюме

  • TCP: Надёжный, упорядоченный, медленнее. Для критичных данных.
  • UDP: Быстрый, ненадёжный, низкая задержка. Для потоков и игр.
  • Выбор: Зависит от требований к надёжности vs скорости.
В чём разница между TCP и UDP? | PrepBro