Что вы используете, когда вам нужен надежный UDP? - PullRequest
89 голосов
/ 20 сентября 2008

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

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

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

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

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

Ответы [ 13 ]

27 голосов
/ 20 сентября 2008

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

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

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

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

25 голосов
/ 20 сентября 2008

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

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

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

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

20 голосов
/ 20 сентября 2008

ENET - http://enet.bespin.org/

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

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

14 голосов
/ 01 октября 2008

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

10 голосов
/ 25 сентября 2008

RUDP - Надежный протокол дейтаграмм пользователя

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

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

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

9 голосов
/ 20 сентября 2008

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

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

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

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

int opt = -1;
if (setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt)))
  printf("Error disabling Nagle's algorithm.\n");
7 голосов
/ 01 августа 2013

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

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

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

4 голосов
/ 15 июня 2009

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

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

4 голосов
/ 20 сентября 2008

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

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

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

3 голосов
/ 15 июня 2009

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

...