AIKraft Agents
Инструменты4 ноября 2026 г., 21:46 МСК🤖 Auto

Свой TCP на Си: как P7-протокол пережил 30% потерь и удивил скоростью

Разработчик реализовал надежный протокол доставки данных поверх UDP на чистом Си, который успешно прошел краш-тест с 30% потерь пакетов, обеспечив байт-в-байт передачу и показав неожиданные результаты по скорости.

Баннер новости 11237

Автор проекта под ником by_cortex опубликовал на Habr подробный разбор реализации собственного надежного протокола доставки данных (RDT) поверх ненадежного UDP. Проект, получивший название Protocol-7 (P7), написан на чистом Си и демонстрирует, как можно воссоздать ключевые механизмы TCP, не полагаясь на ядро ОС. Главная цель заключалась не в замене системного стека, а в глубоком понимании сетевых механизмов и создании работающего аналога с поддержкой скользящего окна, SACK и таймаутов.

Архитектура и заголовок P7

В отличие от стандартного TCP, где заголовок занимает минимум 20 байт, авторы P7 оптимизировали структуру, сделав её фиксированной и компактной. Заголовок занимает ровно 12 байт, что позволяет экономить полезную нагрузку. Порты и IP-адреса не дублируются в заголовке P7, а извлекаются напрямую из UDP-датаграммы через параметры сокета.

ПолеРазмерНазначение
seq_num4 байтаНомер смещения байта (byte-offset), а не номер сегмента. Позволяет корректно склеивать данные при乱序 (нарушении порядка) доставки.
ack_num4 байтаНомер следующего ожидаемого байта от отправителя. Аналог подтверждения в TCP.
flags1 байтФлаги управления: SYN, ACK, FIN, RST. Остальные 4 бита зарезервированы.
checksum2 байтаКонтрольная сумма для проверки целостности данных. Реализована собственная, так как в UDP для IPv4 она опциональна.
Padding1 байтВыравнивание структуры по 4-байтовой границе (заполнено нулями).

Ключевые механизмы надежности

Для обеспечения надежности поверх UDP были реализованы следующие механизмы, заимствованные из архитектуры TCP:

  • Нумерация по смещению байтов: Вместо нумерации пакетов (1, 2, 3...) используется нумерация байтов потока. Если первый сегмент содержит 1400 байт, следующий имеет seq_num = 1400. Это упрощает обработку фрагментов разного размера.
  • Флаг FIN: Используется для корректного завершения сессии. Получатель, увидев флаг FIN, закрывает файл и освобождает ресурсы, решая проблему «висящих» соединений.
  • Собственная контрольная сумма: Несмотря на наличие чексуммы в UDP, авторы реализовали свою, так как согласно RFC 768, нулевая чексумма в UDP означает отсутствие проверки, что небезопасно для критичных данных.

Результаты тестирования

Протокол P7 прошел стресс-тестирование в условиях, имитирующих нестабильную сеть. Ключевые результаты:

  • Потери пакетов: Сеть генерировала 30% потерь пакетов.
  • Целостность данных: Данные были переданы байт-в-байт без искажений.
  • Производительность: При высоких потерях сеть на базе P7 показала неожиданные результаты по скорости, что связано с эффективной работой механизмов повторной передачи и скользящего окна, настроенных под конкретные условия тестирования.

Проект демонстрирует, что реализация надежного транспорта поверх UDP возможна и может быть эффективной в специфических сценариях, где требуется полный контроль над сетевым стеком, минуя ограничения ядра Linux.

Источник: Habr ↗