Вопрос

Если у вас возникла ситуация, когда TCP-соединение потенциально слишком медленное, а UDP-соединение потенциально слишком ненадежное, что вы используете?Существуют различные стандартные надежные протоколы UDP. Какой у вас опыт работы с ними?

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

Меня интересуют различные варианты: TCP находится на одном конце шкалы, а UDP — на другом.Доступны различные надежные варианты UDP, каждый из которых привносит некоторые элементы TCP в UDP.

Я знаю, что TCP часто является правильным выбором, но список альтернатив часто помогает прийти к такому выводу.Такие вещи, как Enet, RUDP и т. д., построенные на UDP, имеют различные плюсы и минусы. Использовали ли вы их, каков ваш опыт?

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

Это было полезно?

Решение

Трудно ответить на этот вопрос без дополнительной информации о предмете проблемы.Например, какой объем данных вы используете?Как часто?Какова природа данных?(например.это уникальные, разовые данные?Или это поток выборочных данных?и т.д.) На какую платформу вы разрабатываете?(например.Desktop/Server/Embedded), чтобы определить, что вы имеете в виду под «слишком медленным», какой сетевой среду вы используете?

Но в (очень!) общих чертах, я думаю, вам придется очень постараться, чтобы превзойти TCP по скорости, если только вы не сможете сделать некоторые серьезные предположения относительно данных, которые вы пытаетесь отправить.

Например, если данные, которые вы пытаетесь отправить, таковы, что вы можете допустить потерю одного пакета (например.регулярно дискретизируемые данные, где частота дискретизации во много раз превышает полосу пропускания сигнала), то вы, вероятно, можете пожертвовать некоторой надежностью передачи, гарантируя, что вы сможете обнаружить повреждение данных (например,за счет использования хорошего crc)

Но если вы не можете допустить потери одного пакета, вам придется начать внедрять методы обеспечения надежности, которые уже есть в TCP.И, не проделав разумного объема работы, вы можете обнаружить, что начинаете встраивать эти элементы в решение для пользовательского пространства со всеми присущими ему проблемами скорости.

Другие советы

Как насчет SCTP.Это стандартный протокол IETF (RFC 4960).

Он имеет возможность фрагментирования, что может помочь в увеличении скорости.

Обновлять:а сравнение TCP и SCTP показывает, что производительность сопоставима, если не использовать два интерфейса.

Обновлять:а хорошая вводная статья.

ЕНЕТ - http://enet.bespin.org/

Я работал с ENET как с надежным протоколом UDP и написал версию, удобную для асинхронных сокетов, для моего клиента, который использует его на своих серверах.Это работает довольно хорошо, но мне не нравятся накладные расходы, которые одноранговый пинг добавляет к бездействующим соединениям;когда у вас много соединений, регулярно пингующих их все, это очень трудоемкая работа.

ENET дает вам возможность отправлять несколько «каналов» данных, причем отправляемые данные могут быть ненадежными, надежными или упорядоченными.Он также включает в себя вышеупомянутый одноранговый пинг, который действует как поддержание активности.

У нас есть клиенты из оборонной промышленности, которые используют UDT (передачу данных на основе UDP) (см. http://udt.sourceforge.net/) и очень довольны этим.Я вижу, что у него также есть дружественная лицензия BSD.

РУДП - Надежный протокол пользовательских датаграмм

Это обеспечивает:

  • Подтверждение полученных пакетов
  • Управление окнами и перегрузками
  • Повторная передача потерянных пакетов
  • Избыточная буферизация (быстрее, чем потоковая передача в реальном времени)

Кажется, он немного более настраиваем в отношении поддержания жизни, чем ENet, но он не дает вам столько возможностей (т.е.все данные надежны и упорядочены, а не только те биты, которые, по вашему мнению, должны быть).Это выглядит довольно простым в реализации.

Как отмечали другие, ваш вопрос очень общий, и будет ли что-то «быстрее», чем TCP, во многом зависит от типа приложения.

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

Есть легкая золотая середина. Алгоритм Нэгла — это часть TCP, которая помогает гарантировать, что отправитель не перегружает получателя большого потока данных, что приводит к перегрузке и потере пакетов.

Если вам нужна надежная, упорядоченная доставка TCP, а также быстрый ответ UDP и вам не нужно беспокоиться о перегрузке при отправке больших потоков данных, вы можете отключить алгоритм Нэгла:

int opt = -1;
if (setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt)))
  printf("Error disabling Nagle's algorithm.\n");

Любой, кто решит, что приведенного выше списка недостаточно и хочет разработать СОБСТВЕННЫЙ надежный UDP, обязательно должен взглянуть на спецификацию Google QUIC, поскольку она охватывает множество сложных крайних случаев и потенциальные атаки типа «отказ в обслуживании».Я еще не пробовал эту реализацию, и, возможно, вам не нужно все, что она предоставляет, но этот документ стоит прочитать, прежде чем приступать к новой «надежной» конструкции UDP.

Хорошей отправной точкой для QUIC является здесь, в блоге Chromium.

Текущий проектный документ QUIC можно найти здесь.

Если у вас возникла ситуация, когда TCP-соединение потенциально слишком медленное, а UDP-соединение потенциально слишком ненадежное, что вы используете?Существуют различные стандартные надежные протоколы UDP. Какой у вас опыт работы с ними?

Ключевое слово в вашем предложении — «потенциально».Я думаю, вам действительно нужно доказать себе, что TCP на самом деле слишком медленный для ваших нужд, если вам нужна надежность вашего протокола.

Если вы хотите добиться надежности от UDP, вам, по сути, придется заново реализовать некоторые функции TCP поверх UDP, что, вероятно, замедлит работу, чем простое использование TCP в первую очередь.

Протокол DCCP, стандартизированный в RFC 4340, «Протокол управления перегрузкой дейтаграмм» может быть тем, что вы ищете.

Кажется реализовано в Linux.

Может быть RFC 5405, Вам будут полезны «Руководство по использованию Unicast UDP для разработчиков приложений».

Вы рассматривали возможность сжатия данных?

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

РУДП.Многие сокет-серверы для игр реализуют нечто подобное.

Лучший способ добиться надежности с помощью UDP — обеспечить надежность самой прикладной программы (например, добавив механизмы подтверждения и повторной передачи).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top