Что вы используете, когда вам нужен надежный UDP?

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

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

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

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

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

Ответ 1

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

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

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

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

Ответ 2

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

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

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

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

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

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

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

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

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

Ответ 6

Как уже указывали другие, ваш вопрос очень общий, и что-то "быстрее", чем 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 algorithm.\n");

Ответ 7

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

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

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

Ответ 8

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

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

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

Ответ 9

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

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

Ответ 10

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

Ответ 11

Считаете ли вы сжатие ваших данных?

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

Ответ 12

RUDP. Многие серверы сокетов для игр реализуют нечто подобное.

Ответ 13

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