Що ви використовуєте, коли вам потрібен надійний UDP?


92

Якщо у вас ситуація, коли TCP-з'єднання потенційно занадто повільне, а UDP-з'єднання потенційно занадто ненадійне, що ви використовуєте? Існують різні стандартні надійні протоколи UDP, який досвід ви маєте з ними?

Будь ласка, обговоріть один протокол на кожну відповідь, і якщо хтось інший вже згадав той, який ви використовуєте, то подумайте про те, щоб проголосувати за нього та використати коментар для деталізації, якщо потрібно.

Мене цікавлять різні варіанти тут, з яких TCP знаходиться на одному кінці шкали, а UDP - на іншому. Доступні різні надійні опції UDP, кожна з яких додає деякі елементи TCP до UDP.

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

Щоб уникнути сумнівів, більше інформації немає, це гіпотетичне запитання, і, на яке я сподівався, з’явиться перелік відповідей, у яких детально описуються різні варіанти та альтернативи, доступні тому, хто повинен прийняти рішення.


1
Це питання, як видається, не стосується теми, оскільки воно проводить опитування щодо технологій
Дейв Хіллер,

Ті, хто вважає, що TCP найкращий у всіх випадках, прочитайте: en.wikipedia.org/wiki/Bandwidth-delay_product
nullptr

У Вікіпедії є хороша таблиця, що порівнює різні аспекти UDP, UDP Lite, TCP, Multipath TCP, SCTP, DCCP та RUDP . SCTP підтримує більшість функцій у цьому списку.
Євген Березовський

@EugeneBeresovsky Я зробив невелике дослідження щодо SCTP, більша частина інформації, включаючи відповіді на SO, датується 2013 роком та раніше. Більшість людей писали тоді, що прийняття SCTP було дуже низьким. Цікаво, як це сьогодні? Також, див. Цю тему stackoverflow.com/questions/1171555/…
Михайло IV

@MichaelIvanov Усиновлення насправді низьке. Але якщо ви маєте намір використовувати його у своєму центрі обробки даних, вам не все одно, що стосується прийняття ззовні, доки комутатори та маршрутизатори не створюють проблем (чого в центрі обробки даних вони не повинні), і у вас є ОС та підтримка бібліотеки, що може бути проблемою, як описано в одній із відповідей на запитання, на яке ви зв’язали.
Євген Березовський

Відповіді:


25

Важко відповісти на це питання без додаткової інформації про область проблеми. Наприклад, який обсяг даних ви використовуєте? Як часто? Яка природа даних? (наприклад, це унікальні, разові дані? Або це потік зразкових даних? тощо) Для якої платформи ви розробляєте? (наприклад, робочий стіл / сервер / вбудований) Для визначення того, що ви маєте на увазі під словом «занадто повільний», який мережевий носій ви використовуєте?

Але загалом (дуже!), Я думаю, вам доведеться по-справжньому постаратися перемогти tcp на швидкість, якщо ви не зможете зробити певних твердих припущень щодо даних, які ви намагаєтеся надіслати.

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

Але якщо ви не можете терпіти втрату одного пакета, то вам доведеться розпочати впровадження типів методів надійності, які вже є у tcp. І, не докладаючи розумного обсягу роботи, ви можете виявити, що починаєте вбудовувати ці елементи в рішення простору користувача з усіма властивими проблемами швидкості.


4
Гаразд, я відкоригую питання. Мене більше цікавлять плюси і мінуси різних надійних протоколів UDP, а не відповідь "використання TCP";)
Лен Холгейт,

9
@Andrew - дуже легко перемогти TCP у двох випадках: (1) у вашому додатку є вищі вимоги щодо надійності, ніж "усі дані, завжди в порядку, без дублікатів, без надмірних черг". Або (2) ви використовуєте багатоадресну передачу. Надійний UDP дуже поширений для середовищ багатоадресної передачі.
Том

4
Крім того, TCP страждає жахливо, коли використовується через WAN-з'єднання (проблеми на довгі відстані). Чому, просто. TCP використовує вікна, де пакети у вікні мають бути заблоковані. Протоколи ACK страждають через затримку через відстань лінії. Google: WAN TCP "швидкість світла"
Ajaxx,

3
@Ajaxx, ти дуже правильно розумієш це, проте TCP / IP робить це навмисно через останній крах в Інтернеті. Якщо ви робите протокол з високою швидкістю передачі даних без будь-якого контролю перевантаження, в основному соромтесь. Якщо ви є власником мережі, тоді дивіться.
Кевін Нісбет,

2
"де частота дискретизації значно перевищує частоту Найквіста" - частота дискретизації завжди вдвічі більша за частоту Найквіста, за визначенням.
Стів

27

А як щодо SCTP . Це стандартний протокол IETF (RFC 4960)

Він має можливість шматування, що може допомогти швидкості.

Оновлення: порівняння між TCP та SCTP показує, що продуктивність порівнянна, якщо не можна використовувати два інтерфейси.

Оновлення: приємна вступна стаття .


Це добре, мене більше цікавлять речі, які можна побудувати на вершині UDP, а не на основі IP, але це, безумовно, те, що вміщується в просторі рішень.
Лен Холгейт

SCTP має безліч чудових функцій (наприклад, багатоканальне підключення), а з частковим розширенням надійності (RFC 3758) це неймовірно гнучкий варіант. Він включений в останні версії ядра Linux, але для Windows вам доведеться встановити власний стек SCTP.
Ендрю Джонсон,

6
SCTP можна тунелювати через UDP. tools.ietf.org/id/draft-ietf-sigtran-sctptunnel-00.txt
Майлз

Спасибі Майлз, це корисне посилання!
Лен Холгейт

1
Так ... Але щось, що побудовано поверх UDP, а не на тому ж рівні, що й UDP, швидше за все, буде простіше впровадити в просторі користувачів, принаймні в Windows ...
Лен Холгейт

21

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

Я працював з ENET як надійний протокол UDP і написав асинхронну версію розетки для мого клієнта, який використовує його на своїх серверах. Це працює досить добре, але мені не подобаються накладні витрати, які пінг-рівний пінг додає до інших простоїв з'єднань; коли у вас багато зв’язків, регулярно перевіряти їх усі - це дуже напружена робота.

ENET надає вам можливість надсилати кілька "каналів" даних, а дані, що надсилаються, бути ненадійними, надійними або послідовними. Сюди також входить вищезазначений пірінг-пінг, який виконує функції збереження життя.


14

У нас є деякі клієнти оборонної промисловості, які використовують UDT (передача даних на основі UDP) (див. Http://udt.sourceforge.net/ ) і дуже задоволені цим. Я бачу, що це також має дружню ліцензію BSD.


2
Чи можете ви детальніше розповісти про своїх клієнтів та випадки їх використання, особливо в оборонному секторі? Можливо, ні, але це варто пострілу. Насправді я підкинув ідею про свою UDT у програмі передачі файлів своєму начальству, але вона ще нікуди не дійшла.
Thomas Owens,

10

RUDP - надійний протокол датаграм користувачів

Це забезпечує:

  • Підтвердження отриманих пакетів
  • Контроль за вікнами та заторами
  • Повторна передача втрачених пакетів
  • Надбуферизація (швидше, ніж потокове передавання в реальному часі)

Це здається дещо більш налаштованим щодо збереження живих, ніж ENet, але це не дає вам стільки варіантів (тобто всі дані є надійними та мають послідовність, а не лише ті біти, які, на вашу думку, мають бути). Це виглядає досить прямо в реалізації.


Я дивився на це, але, здається, не так багато реалізацій. Отримали рекомендацію?
Микола

Ні вибач. Зрештою я не використав його і завжди збирався робити реалізацію з нуля.
Len Holgate

9

Як зазначали інші, ваше запитання є дуже загальним, і чи є щось швидшим, ніж 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");

Як я вже говорив, припускаючи, що TCP знаходиться на одному кінці шкали, а UDP - на іншому, що там ще є.
Лен Холгейт

Якщо ви хочете бути педантичними, більшість обговорюваних протоколів побудовані на вершині UDP.
smo

Припущення, що TCP знаходиться на одному кінці, а UDP - на другому, є хибним. наприклад, UDP не має контролю потоку, ви можете легко надсилати пакети занадто швидко, змушуючи маршрутизатор між ними скидати їх усі. Тоді що ти робиш? Ігнорувати втрачені пакети або відправити їх повторно? Повторно надіславши їх, ви в кінцевому підсумку зміните TCP більш-менш. Ще одним варіантом надійного зв'язку є SCTP.
nos

1
Швидка реакція не обов'язково дорівнює високій пропускній здатності.
Matt

1
Я не погоджуюсь. Коли nagle використовується на протоколах, заснованих на TCP, з великою кількістю менших пакетів, він об'єднує їх і створює більше більших пакетів. Це спричиняє невелику затримку надсилання, тому запізнення може зрости дуже незначно. Однак пропускна здатність може бути меншою при вимкненому nagle, оскільки більше пакетів = більше заголовків пакетів = більші накладні витрати. Пакети, що скидаються в локальну мережу, як правило, пов’язані із заповненням вхідних буферів. Якщо у вас багато клієнтів, які надсилають дані одному хосту, це може не мати різниці. Я не вірю, що вимкнення та увімкнення nagle буде впливати на це на практиці.
Matt

8

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

Хороший стрибковий пункт для QUIC - тут , у блозі Chromium.

Поточний проектний документ QUIC можна знайти тут .


4

Якщо у вас ситуація, коли TCP-з'єднання потенційно занадто повільне, а UDP-з'єднання потенційно занадто ненадійне, що ви використовуєте? Існують різні стандартні надійні протоколи UDP, який досвід ви маєте з ними?

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

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


Так, Ендрю Еджкомб сказав стільки ж, але, як я вже сказав, мене цікавлять плюси і мінуси ТАКИХ альтернатив. Без цього списку альтернатив та їх плюсів і мінусів важко визначитися, що найкраще.
Лен Холгейт

Враховуючи відому функцію надійності, іноді потік UDP можна налаштувати вручну, щоб випередити потік TCP в ОС HTE. Хоча рідко.
Джошуа

1
@ 17 з 26, я погоджуюсь з Леном Холгейтом, TCP за певних обставин буде повільнішим, ніж надійний UDP. Як і мережа з високим рівнем BDP, припустимо, у вас є Інтернет-з'єднання з Китаю в Нью-Йорк на 1 Гбіт / с, я впевнений, що TCP буде відмовити, щоб використовувати майже всю швидкість 1 Гбіт / с. TCP краще для більшості з'єднань на Землі, але не для мережі з продуктом із затримкою високої пропускної здатності.
nullptr


3

Можливо RFC 5405 , "Вказівки щодо використання Unicast UDP для дизайнерів програм" будуть корисними для вас.


2

Ви розглядали можливість стиснення ваших даних?

Як зазначено вище, нам не вистачає інформації про точний характер вашої проблеми, але стиснення даних для їх транспортування може допомогти.


1
Особливо з сучасними бібліотеками стиснення. Деякі з них швидкі, як memcpy. наприклад lz4.
Matt


-3

Найкращий спосіб досягти надійності за допомогою UDP - це побудова надійності в самій прикладній програмі (наприклад, шляхом додавання механізмів підтвердження та повторної передачі)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.