Что вы используете, когда вам нужен надежный UDP?
Если у вас есть ситуация, когда TCP-соединение потенциально слишком медленно, а UDP-соединение потенциально слишком ненадежно, что вы используете? Существуют различные стандартные надежные протоколы UDP, какой опыт у вас есть с ними?
пожалуйста, обсудите один протокол за ответ, и если кто-то уже упомянул тот, который вы используете, то рассмотрите возможность голосования их и использования комментария для разработки, если это необходимо.
меня интересуют различные параметры здесь, из которых TCP находится на одном конце шкалы, а UDP-на другом. Доступны различные надежные параметры UDP, и каждый из них приносит некоторые элементы TCP в UDP.
Я знаю, что часто TCP является правильным выбором, но наличие списка альтернатив часто полезно, чтобы помочь прийти к этому выводу. Такие вещи, как Enet, RUDP и т. д., которые построены на UDP, имеют различные плюсы и минусы, вы их использовали, каков ваш опыт?
во избежание сомнений больше информации нет, это гипотетический вопрос, и я надеялся, что он вызовет список ответов, в которых подробно описаны различные варианты и альтернативы, доступные тому, кто должен принять решение.
13 ответов:
трудно ответить на этот вопрос без дополнительной информации о домене проблемы. Например, какой объем данных вы используете? Как часто? Какова природа этих данных? (напр. это уникальный, один от данных? Или это поток выборочных данных? так далее.) Для какой платформы вы разрабатываете? (напр. рабочий стол / сервер / встроенный) Чтобы определить, что вы подразумеваете под "слишком медленным", какой сетевой носитель вы используете?
но в (очень!) общие условия я думаю, что вы собираетесь нужно очень постараться превзойти tcp для скорости, если вы не можете сделать некоторые жесткие предположения о данных, которые вы пытаетесь отправить.
например, если данные, которые вы пытаетесь отправить, таковы, что вы можете терпеть потерю одного пакета (например. регулярно отбираемые данные, где частота дискретизации во много раз превышает полосу пропускания сигнала), то вы, вероятно, можете пожертвовать некоторой надежностью передачи, гарантируя, что вы можете обнаружить повреждение данных (например. через использование хорошего crc)
но если вы не можете терпеть потерю одного пакета, то вам придется начать вводить типы методов для надежности, которые уже есть у tcp. И, не вкладывая разумный объем работы, вы можете обнаружить, что начинаете строить эти элементы в решение пользовательского пространства со всеми присущими ему проблемами скорости.
а как же SCTP. Это стандартный протокол IETF (RFC 4960)
Он имеет возможность фрагментации, которая может помочь для скорости.
обновление: a сравнение между TCP и SCTP показывает, что производительность сопоставима, если не могут быть использованы два интерфейса.
обновление: a хорошая вступительная статья.
ENET - http://enet.bespin.org/
Я работал с ENET как надежный протокол UDP и написал асинхронную версию сокетов для моего клиента, который использует его на своих серверах. Он работает довольно хорошо, но мне не нравятся накладные расходы, которые одноранговый пинг добавляет к другим бездействующим соединениям; когда у вас есть много соединений, пингующих все из них регулярно-это много напряженной работы.
ENET дает вам возможность отправить несколько каналов данных и для данных, отправляемых быть ненадежными, надежными и последовательными. Он также включает в себя вышеупомянутый одноранговый пинг, который действует как keep alive.
У нас есть некоторые клиенты оборонной промышленности, которые используют UDT (передача данных на основе UDP) (см. http://udt.sourceforge.net/) и очень довольны этим. Я вижу, что это также имеет дружественную лицензию BSD.
RUDP - Надежный Протокол Пользовательских Дейтаграмм
обеспечивает:
- подтверждение полученных пакетов
- управление окнами и перегрузками
- повторная передача потерянных пакетов
- Overbuffering (быстрее, чем в режиме реального времени потокового)
Он кажется немного более настраиваемым в отношении сохранения жизни, чем 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 для разработчиков приложений " будет полезно для вас.
вы рассматривали возможность сжатия ваших данных ?
Как было указано выше, нам не хватает информации о точном характере вашей проблемы, но сжатие данных для их перевозки может помочь.
RUDP. Многие сокетные серверы для игр реализуют нечто подобное.
лучший способ добиться надежности с помощью UDP-это построить надежность в самой прикладной программе (например, добавив механизмы подтверждения и повторной передачи)
Comments