Чи UDP все ще кращий, ніж TCP, для важких ігор у режимі реального часу?


71

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

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

Це змушує мене замислитися: чи UDP все ще перевершує за швидкістю та затримкою? Чи могли останні оптимізації TCP змусити TCP працювати краще, ніж UDP?


25
З UDP немає гарантії, що ваші пакети будуть отримані або навіть замовлені, що лише робить UDP швидше, ніж TCP.
Натан

4
@KaareZ, що ти означає швидше впровадити?
Натан

2
@nathan Що простіше розробити свою програму за допомогою TCP, ніж UDP. Я хочу знати, чим далі всі оптимізації TCP зробили TCP кращим варіантом з точки зору продуктивності.
KaareZ

3
@KaareZ Я не експерт, але давайте подумаємо про це. Як TCP може бути кращим з точки зору продуктивності та залишатися надійним протоколом? Ти не можеш мати все. TCP зроблений для надійності. Справжнє питання - чому ви хочете використовувати TCP у своїй грі?
Натан

7
UDP є кращим, ніж TCP, якщо і тільки якщо ви зможете (= досвідчений мережевий програміст низького рівня) ефективно реалізувати лише необхідні функції TCP, які вам знадобляться всередині нього. Відмова від непотрібних функцій TCP для продуктивності.
wondra

Відповіді:


119

Ні, UDP як і раніше перевершує за затримкою продуктивності та завжди буде швидше, завдяки філософії двох протоколів - якщо припустити, що ваші дані зв'язку були розроблені з використанням UDP або будь-якого іншого збиткового зв'язку.

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

  1. Виявлено втрату першого оновлення.
  2. Потрібна повторна передача першого оновлення.
  3. повторна передача надійшла та була оброблена.

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

Це вимагає, щоб ви надсилали потрібний тип даних і проектували ваше спілкування таким чином, щоб втрата даних була прийнятною.

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

EDIT - Додавання додаткової інформації для включення / вирішення деяких коментарів:

Зазвичай рівень втрат пакетів на Ethernet дуже низький, але він стає набагато вищим, коли підключений WiFi або якщо користувач здійснює завантаження / завантаження. Припустимо, у нас ідеально рівномірні втрати пакету - 0,01% (в одну сторону, а не в зворотному напрямку). Під час шутера від першої особи клієнти повинні надсилати оновлення щоразу, коли щось відбувається, наприклад, коли курсор миші повертає програвач, що відбувається приблизно 20 разів за секунду. Вони також можуть надсилати оновлення за кадр або через фіксований інтервал, який би становив 60-120 оновлень за секунду. Оскільки ці оновлення надсилаються в різний час, вони / повинні надсилатися в одному пакеті за оновлення. У грі з 16 гравцями всі 16 гравців відправляють ці 20-120 пакетів в секунду на сервер, в результаті чого в цілому виходить 320-1920 пакетів. З нашою швидкістю втрати пакетів 0,01%, ми очікуємо втрати пакету кожні 5,2-31,25 секунди.

На кожен пакет, який ми отримаємо після втраченого пакету, ми надішлемо DupAck, а після 3-го DupAck відправник повторно передасть втрачений пакет . Отже, час, який потрібен TCP для ініціювання повторної передачі, становить 3 пакети, плюс час, необхідний для приходу останнього DupAck до відправника. Тоді нам потрібно дочекатися прибуття повторної передачі, тому загалом чекаємо 3 пакети + 1 затримка в обидва кінці. Затримка в обидва кінці зазвичай становить 0-1 мс в локальній мережі та 50-200 мс в Інтернеті. 3 пакети зазвичай прибувають за 25 мс, якщо ми надсилаємо 120 пакетів в секунду, а за 150 мс - якщо ми надсилаємо 20 пакетів в секунду.

На противагу цьому, з UDP ми відновляємось із втраченого пакету, як тільки отримуємо наступний пакет, тому ми втрачаємо 8,3 мс, якщо надсилаємо 120 пакетів в секунду, і 50 мс, якщо надсилаємо 20 пакетів в секунду.

Завдяки TCP речі отримують більш суттєвий характер, якщо нам також потрібно врахувати Nagle (якщо розробник забуде вимкнути надсилання коалесценції або не може відключити затримку ACK ), уникнення перевантажених мереж або якщо втрата пакету досить погана, що нам доведеться обліковувати кілька втрати пакетів (включаючи втрачені Ack і DupAck). За допомогою UDP ми можемо легко писати швидший код, оскільки нам просто не байдуже бути хорошим громадянином мережі, як це робить TCP.


Примітка: UDP може транслювати локальну мережу (можлива перевага), і оскільки Vista вимагає адмін-сервера для запуску сервера / трансляції на UDP (недолік) (UAC / брандмауер, як правило, не повідомляє дії користувача).
PTwr

7
"Якщо ви надсилаєте 2 оновлення на TCP, і пакет першого оновлення втрачається" Правда, але які шанси на це відбудуться? За словами pingman : "Що-небудь понад 2% втрат пакету протягом певного періоду часу є сильним показником проблем".
mucaho

30
@Peter, ви забуваєте, що в TCP кожен скинутий пакет зупиняє кожен наступний пакет. З 100мс пінг легко може пройти 300-500мс, перш ніж цей пакет буде повторно переданий і отриманий, так що це 6-10 пакетів, які затримуються кожні 33 секунди. Це, безумовно, буде помітно в FPS-подібному землетрусу.
BlueRaja - Danny Pflughoeft

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

23
У такій грі, як Quake, втратити перший пакет не має значення. У FAR менше часу знадобиться для виявлення втрати та повторної передачі першого пакету, ви вже мали б передати другий пакет, що робить перший в будь-якому випадку застарілим. Це та сама причина, що багато голосових та відео-додатків у реальному часі також використовують UDP. Якщо пакет випаде, ви краще просто втратити аудіо 0,02 секунди, ніж затримати весь потік на повну секунду або більше. Це, як правило, стосується ігор у режимі реального часу, оскільки ви хочете знати, де зараз об’єкт , а не 1,5 секунди тому.
reirab

19

Ми погоджуємось, що TCP та UDP є протоколами, побудованими на основі IP-адреси , чи не так? IP визначає, як повідомлення надходять через Інтернет, але нічого не стосується структури, формату повідомлень. Сюди йдуть протоколи TCP та UDP. Вони використовують властивості IP, але дозволяють програмісту зосередитися на обміні повідомленнями, не турбуючись про нижні шари мережевої комунікації. І це чудово, адже спілкування з аналоговими сигналами в проводах безпосередньо було б болісно.

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

  • З іншого боку, UDP є протоколом, орієнтованим на управління користувачем. Використовуючи UDP для надсилання наших дейтаграм , ми не можемо бути впевнені, що датаграма коли-небудь прибуде до місця призначення чи ні (і ми маємо на увазі тут математичну впевненість: коли ми надішлемо пакет, він, ймовірно, прийде, але ми не можемо бути впевнені в 100%). Крім того, коли пакет втрачено, він не буде виявлений і не надсилається знову.

На даний момент TCP виглядає як ідеальне рішення всіх наших проблем. Це надійно, швидко, він вирішує затримку підключення для нас, відстежуючи, які пакети надійшли та які пакети нам ще потрібно надіслати.

АЛЕ , дивіться далі. Єдина перевага, яку нам надає UDP, - це її швидкість, і це саме те, чого ми дійсно хочемо. Пакет UDP просто створюється, перевіряється і надсилається без особливих елементів керування, тому що так працює протокол UDP. TCP-пакет повинен бути створений, позначений, позначений підсумком, і коли він надходить, ACK надсилається назад, щоб повідомити відправника "пакет x тут, продовжуйте дію" , і коли цей сигнал не надсилається, це означає, що такий пакет x повинен бути надісланий знову.

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

Так, але не тільки. UDP в основному перевагу над TCP, головним чином, оскільки його висока швидкість - це ідея для управління високою передачею даних та управління ними. Це трапляється, коли, якщо припустити, що така відеоігра працює на детермінованому блокуванні кроку (те, що відбувається на сервері, ідентично реплікується на будь-який клієнт незалежно від затримки мережі), пакет оновлення втрачається і ніколи не потрапляє до місця призначення. TCP повторно надішле такий пакет, і наступні пакети будуть скинуті, оскільки надходять не в порядку, а потім будуть повторно відправлені після втраченого. UDP набагато толерантніший у цьому сценарії: він не піклується про цей пакет, тому що надходять нові оновлення. Втрачене оновлення не відображається, натомість фізика ігор інтерполюється після використовуваного методу інтеграції та отриманого останнього оновлення.

TCP викликає тремтіння, коли затримка досить висока, UDP не:

<video style="min-width: 100% height: auto" autoplay="" preload="auto" loop="true"><source src="https://gafferongames.com/videos/deterministic_lockstep_tcp_250ms_5pc.mp4" type="video/mp4"><source src="http://173.255.195.190/cubes_deterministic_lockstep_tcp_250ms_5pc.webm" type="video/webm">Your browser does not support the video tag.</video>

Це змушує мене замислитися, чи UDP все ще перевершує за швидкістю та затримкою.

Ну так, так і є надовго . Більше про TCP проти UDP ви можете прочитати тут .


8
TCP використовує потоки байтів, а не дейтаграми. UDP використовує дейтаграми. Хороші реалізації TCP не дозволять пакетам, які вийшли з ладу, але вміст пакету не може бути доступним для програми, якщо або до того моменту, поки не будуть отримані всі попередні пакети. Таким чином, якщо один пакет загубиться, відправник може не потребувати повторної передачі всього, що слідує за втраченим пакетом, але приймаюча програма не побачить нічого, що втратило пакет, поки цей пакет не буде повторно переданий (після чого додаток миттєво побачить вміст цього пакет і ті, що після нього).
supercat

@supercat На жаль, TCP не має жодного способу сказати відправника, які саме пакети він зробив та не отримав. Він має лише механізм "Я отримав усі байти через x порядковий номер." Якщо відправник повторно передає пакети, які одержувач вже отримав, він просто ігнорує копії.
reirab

@reirab: Я думав, що існували деякі сучасні розширення, які включали цю функцію, хоча навіть без цього я думаю, що реалізація, яка надіслала дані до байта # 1050 000, але отримала лише аки для даних до 1 000 000, через секунду не почувши будь-який хід за що-небудь минуле 1 000 000, почніть з надсилання блоку даних від 1 000 000 до 1 000 500 або близько того, а потім чекайте відповіді. Якщо він отримує доступ до даних до 1 500 000, він може потім передати більше даних; якщо він отримує доступ до даних до 1050 000, він може пропустити повторну передачу.
supercat

1
@Giorgio IP нічого не вказує про аналогові сигнали. Це робиться на фізичному шарі. IP працює на два шари вище, ніж на мережевому рівні. IP не міг би перейматися тим, чи біти переходять через волокно, супутникове посилання або модем з комутованим набором 14,4 кбіт / с. UDP і TCP - це шар вгору від IP, на транспортному шарі. Крім того, як каже supercat, TCP представляє потік інтерфейсу програми, а не інтерфейс дейтаграми, як UDP.
reirab

@supercat Хм ... ви можете мати рацію щодо сучасних розширень, хоча це, звичайно, не є частиною оригінального стандарту TCP. ACK просто має порядковий номер. Я припускаю, що реалізація TCP зазвичай починає повторну передачу всього вікна відправки, якщо пакет опускається, а не чекає цілого RTT для кожного пакету. Це додало б величезної кількості затримок, якби кілька послідовних пакетів було втрачено за дуже малий прибуток.
reirab

9

TCP <- протокол управління передачею. Він створений для управління передачею.

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

  • Одержувач виявляє пакет, що відсутній, повідомляє відправника сповільнити (вдвічі зменшити швидкість).
  • Одержувач виявляє неправильне вхідне замовлення пакетів (можливо, вони взяли різні мережеві шляхи), повідомляє відправника сповільнитись - і btw, одержувач не прийме подальших пакетів, поки не з’явиться відсутній. Для вирішення цього потрібен час.
  • Відправник виявляє перевантаженість мережі (наприклад, повільний час в обидва кінці), додає затримку.
  • Одержувач не може йти в ногу зі швидкістю (вхідний буфер стає занадто заповненим), просить відправника додати затримку (контроль потоку).
  • Серед одержувачів є один повільний приймач (високий пінг-ублюдок, плач, як їх називають), затримка (може бути) додана в домашньому господарстві.

Додатково

  • Алгоритм Nagle може тримати дані відправників на утриманні, поки не буде більше надіслати (щоб ефективніше використовувати кадри даних). Часово важливі дані затримуються.
  • Я вважаю, що звичайні домашні маршрутизатори з wlan можуть робити розумні речі (сповільнювати), щоб згладити пропускну здатність TCP між декількома клієнтами (інтерфейс wlan є вузьким місцем, навіть якщо гра не використовує його). Відноситься до мовлення / багатоадресної передачі, тобто. "інші" дані можуть зменшити пропускну здатність TCP.
  • TCP ACKзнає все, що не потрібно для ігрового середовища. Немає сенсу ACKing за кожне оновлення фізики. Досить розібратися, наприклад, раз на секунду чи подібне. Якщо клієнт (або сервер) мовчить довший час, тоді настав час реагувати.

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

UDP нічого з цього не робить. Це спрацьовує за вашою волею, тільки те, що не можна очікувати, що воно вдарятиметься кожного разу, - натомість ціль повинна оголосити, що «ви давно не стріляли, чому?». Ще можна створити власні власні пакети ACK, помістити декілька записів у один пакет тощо. А також важливо, керуйте NAT-траверсією. UDP найбільш безумовно підходить для ігор з низьким попитом на затримку.


1
Примітка: Алгоритм Nagle може бути відключений, наприклад, для Linux .
mucaho

Nagle може працювати проти (і може бути відхилений від сторони, встановивши кожен пакет на "натискання" додатком). Тим часом Delayed Ack працює на користь TCP, він дозволяє відправнику помістити більше байтів на дріт, поки вікно відправлення не заповниться (в ідеалі як велике як буфер прийому знаходиться на іншій стороні) незалежно від того, чи був помічений ак.
Джефф Меден

4
Це протокол управління передачею .
ysdx

1
Наберіть ці слова мільйон разів ... thx - фіксовано.
Stormwind

3

Ви можете порівняти першу діаграму RFC 768 (UDP) з першою діаграмою RFCP 793 (TCP), сторінка 15 .

Обидва показують 16 біт для "вихідного порту", а потім 16 біт для "порту призначення". Обидва показують 16 біт для "контрольної суми". Згідно RFC 768, "процедура контрольної суми UDP така ж, як і в TCP".

Тоді як довжина UDP містить деталі діаграми UDP, довжина TCP є частиною "96-бітового псевдо заголовка", описаного на сторінках 15 і 16.

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

Інша причина полягає в тому, що TCP "тристоронній рукостискання" означає, що відправник повинен чекати відповіді. Ця вимога вводить додаткові накладні витрати, які UDP не обробляє. Існує причина, чому більшість ваших Інтернет-комунікацій починається з деякого зв'язку UDP. Базовий DNS використовує UDP, тому що запит і відповідь можуть бути виконані за меншу кількість кроків, ніж процес "тристороннього рукостискання" TCP. Особливість TCP відстеження втрачених пакетів є досить незвичною, тому що комп'ютер може просто зробити новий запит, а не намагатися повідомити віддаленій системі про те, що існує невиконаний попередній запит.


Хоча англійські підсумки (як це видно в деяких інших відповідях) приємні, просто мати точний і точний опис може бути найпростішим.
TOOGAM

Ви маєте на увазі 16 біт, а не байт!
jcaron

О, нерозумно мені. це приклад того, чому технічно точні відповіді приємні; вони легко визначити помилки і побачити правильну інформацію. Я зафіксував відповідь. Дякую @jcaron
TOOGAM

2

Подумайте, що відбувається на мить. Для спрощення сценаріїв у вас є два варіанти, коли ви намагаєтеся надіслати зміну стану (наприклад, ваш гравець просто змінив напрямок, або вистрілив з пістолета, або інший гравець просто почав бомбу):

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

Якщо припустити, що до цього не було потрібного оновлення, час, коли це сингулярне оновлення надходить у 1 проти 2, не буде дуже різним. Це одна поїздка від сервера до клієнта. Але, скажімо, замість того, щоб просто вибухала бомба, ви намагаєтесь постійно ретранслювати діяльність того, хто пробігає лабіринт; плетіння, притуплення, зйомка тощо. У випадку з UDP кожна дія буде відправлена ​​у дейтаграмі, як тільки це станеться. У випадку TCP кожна дія буде надіслана в пакеті лише в тому випадку, якщо серверу дозволено надсилати. Що говорить, що дозволено надсилати? Має місце у вікні TCP (якщо припустити, що затримка ack активна), щоб повідомлення можна було поставити на провід. Якщо ні, то перед відправленням доводиться чекати, коли прибуде прибуток від клієнта.

Як довго занадто довго? Коли багатокористувацька розробка шутерів від першої особи вдарила в кінці 90-х - початку 2000-х, зв'язки з низькою затримкою не були поширеними. Для комутованого модему типова одностороння затримка становить 180 мс. Чекати навколо акка, перш ніж надсилати інше оновлення, фактично подвоюючи цей час на 360 мс, було болісно; навіть початківці користувачі напевно могли відчути різницю. Коли широкосмугові з’єднання зафіксувались, вони значно скоротили затримку, але вона все ще зберігалася, коли пропускна здатність не вистачала (досить часто в деяких районах). Тож перевага найменшої можливої ​​затримки зберігалася.

Сучасні домашні зв’язки та взаємозв’язки змінили це до того, що регіональна затримка, навіть у переповнений час доби, знаходиться в межах 15 мс і нижче. Вибір TCP замість UDP був би непомітним у більшості випадків, оскільки затримка "досить низька". Однак, як і раніше існує тенденція UDP надавати пріоритет перед TCP, враховуючи його історію як протокол низької затримки. Отже, поки що (а можливо, і деякий час у майбутньому) UDP буде віддавати перевагу спілкуванню в режимі реального часу.


Затримка буде достатньо низькою, за винятком того, що за замовчуванням записи TCP надсилаються лише тоді, коли дані для запису перетинають певний поріг або час очікування (зазвичай 200-1000 мс). Якщо вам потрібен TCP в системі з низькою затримкою з малою пропускною здатністю, ви повинні відключити цю функцію і переконайтеся, що ви не записуєте окремі байти весь час (наприклад, ви більше не трактуєте потік TCP як потік, і ви робите вигляд, що ви замість цього ви маєте справу з окремими повідомленнями). Вам не доведеться чекати ACK, якщо ваші буфери не заповнені, що навряд чи трапиться в звичайній грі в режимі реального часу.
Луань

1
@Luaan Enter: прапор TCP PSH. Коли додаток передає його стеку, пакет відправляється негайно, не чекаючи додаткових даних. Багато програм використовує це успішно (наприклад, telnet та ssh).
Джефф Меден

2

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

Ваші припущення помилкові. TCP і UDP відрізняються насамперед тим, яку модель вони представляють (ненадійні дейтаграми порівняно з надійним віртуальним потоком на замовлення).

Вони не відрізняються за обсягом ("високе використання даних") або пропускною здатністю. TCP просуне стільки ж даних, скільки і UDP, він легко наситить фізичний кабель.

За наявності втрати пакету вони відрізняються затримкою, але лише в такому стані. В іншому випадку TCP має настільки ж низьку затримку, як і UDP (надайте або займіть, можливо, кілька десятків наносекунд, оскільки мережевий стек має трохи більше логіки, але це досить недбало).
Існує незначна різниця у розмірі заголовка, тому технічно більше байтів повинно робити його за допомогою дроту в послідовних лініях, але це теж досить невдало. Це дійсно має значення лише для масових переказів, і тоді це приблизно 0,5% різниці. Більшість людей з домашнім маршрутом доступу DSL через увесь свій трафік через банкомат, що додає на 10% накладні витрати протоколу (5 контрольних байт на 48 байт корисного навантаження, плюс часткові кадри), і ніхто навіть не помічає.

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

Ігри, як правило, використовують UDP не тому, що він перевершує один із згаданих способів - це не так - або тому, що ви можете зменшити тремтіння на половину мілісекунди, застосовуючи надійність без порядку, а тому, що ігри (як і IP-телефонія) часто містять багато дуже мінливих даних, таких як, наприклад, оновлення позицій.
Ці мінливі дані регулярно і швидко застарівають як з часом, так і з наступною дейтаграмою, що надходить. Це означає, що нічого більше і нічого менше, ніж ви насправді не надто дбаєте про те, щоб бути 100% надійними (або в порядку).

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

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

Зверніть увагу на те, що втрата пакету - це нормальний стан. Хоча IP, як правило, "досить надійний", пакети, які періодично скидаються, можуть трапитися, і це станеться . Хоча втрачаються пакети, як правило, досить рідкісні (<1% тут), це не є чимось надзвичайним чи теоретичним чи свідченням того, що щось порушено. Це абсолютно нормально.
Кожна об’ємна передача TCP обов’язково включає втрачені пакети, наприклад (це працює як контроль заторів).


2

У MPG з високою пропускною здатністю вам не байдуже, якщо ви пропустили пакет, який надає вам місцезнаходження та стан здоров’я монстра № 425, тому що ви отримаєте ще одне оновлення за деяку частину секунди. Це і є приклад, коли UDP змушує TCP виглядати дурним, щоб змусити вас чекати миттєво застарілих даних.

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

Ось простий опис того, що відбувається.

UDP - ізолювати шматок O'data.
Складіть пакет.
Інкапсулювати в IP.
Відправте його.

TCP - виділити потокову інформацію.
Зробіть пакет з передньої частини потоку.
Інкапсулювати в IP.
Зачекайте місця у вікні TCP.
Відправте його.
Продовжуйте відправляти доставку, поки не буде отримано квитанцію або час очікування.
Залишайтеся у вікні TCP, поки не буде отримано квитанцію або час очікування.

Доставка просто означає, що вона зробила це через місцевий NIC, не більше.

Прийом квитанції TCP гарантує як отримання даних, так і звільняє місце у вікні для наступного пакету.

Повторне надсилання (трохи) збільшує ймовірність можливого отримання.

Пакети TCP знову збираються з іншого боку як упорядкований потік даних. UPD-пакети приймаються як окремий пакет. Протокол не зберігає порядок.

TCP добре підходить для передачі необхідних даних та великих замовлених обсягів даних. TCP надає повідомлення про постійний збій. TCP самозапускається через задушливі труби (посилання: вікно). TCP має рукостискання для уповільнення ініціалізації. TCP вимагає "з'єднання" перед передачею.

UDP просто ставить дані на провід і дозволяє продовжувати, не чекаючи вікон та повторних передач. UDP вибухне на повній швидкості в задушливу трубу, незалежно від того, скільки даних втрачено.

Я розробив і написав комерційно застосовану утиліту для передачі файлів UDP Multicast. Я працював над стеками IP. Це лише основи, sans minua. Пояснення "розеток, MTU та інших веселих іграшок" було трохи більше, ніж було б корисно для цього питання.

Ps (я не можу додавати коментарі, щоб відповісти на коментарі) UDP також корисний для даних, бажаних, але не обов'язкових. Приклад цього виправлення помилок вперед - це багато непотрібних, але бажаних пакетів.


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

1

Чи всі оптимізовані маршрутизатори TCP змусили TCP працювати краще, ніж UDP?

Ще одне питання: чи означає "важкі дані", що ви часто завантажуєте сцени?

Якщо так, то, можливо, вам доведеться інтенсивно надсилати великі фрагменти даних (> 1k), в яких TCP може бути набагато ефективнішим, оскільки, особливо, на стороні сервера, NIC надаватимуть різні розвантаження, які мають таку ж кількість циклів. Додаток для користувальницького простору може видавати великі записи з TCP, тоді як в UDP спроба надіслати більше байтів розміру заголовків MTU спричинить фрагментацію IP та інші накладні витрати, що знищить продуктивність


Це гра «воксель», так що так, їй потрібно буде надіслати багато даних сцени.
KaareZ

@KaareZ Ну, напевно, ви все одно хочете відправити їх як окремі незалежні повідомлення в цьому випадку за допомогою власних механізмів повторної передачі. Minecraft стартував через TCP, і він був майже не доступний через Інтернет; перехід на UDP був щасливим приводом для більшості людей. Основна ідея полягає в тому, що, коли ви надсилаєте 20 фрагментів даних вокселів, а перший "втрачається", він не повинен блокувати інші 19 фрагментів, щоб відображатися, як тільки ви отримуєте дані; коли ви виявите, що перший відсутній, ви повторно передаєте. На TCP всі ці 19 принаймні зупиняються і повторно передаються в гіршому випадку.
Луань

2
@Luaan Minecraft не перейшов на UDP для фактичного гри. Навіть останні версії все ще використовують TCP. Немає щасливого випадку ... :( Єдина частина Minecraft, яка використовує UDP, - це список серверів, щоб пінг-
сервіси

1

Ні UDP або TCP (або будь-який інший варіант) знаходиться поза правий вище , навіть з точки зору швидкості / часу очікування. Ваш вибір повинен бути зроблений залежно від вимог вашої заявки. Для цього слід порівняти функції, пропоновані кожним протоколом, розуміючи, що більше функцій передбачає більше витрат. Отже, якщо мета полягає в тому, щоб мінімізувати затримку або максимально підвищити швидкість, то вам слід вибрати протокол з якомога меншими можливостями, але зберігаючи основні функції, необхідні для задоволення ваших вимог.

Порівняння протоколів

Взагалі кажучи, UDP (User Datagram Protocol) пропонує найменший обсяг функцій. Це спрощення в тому, що ви надсилаєте дані без будь-якого роду отримання / підтвердження.

З іншого боку, TCP (протокол управління передачею) пропонує найбільшу кількість функцій, необхідних для надійного зв’язаного зв'язку. Зв'язок TCP надсилає дублікати або більше пакетів і позначає їх інформацією про замовлення. Після отримання в пункт призначення, ACK (підтвердження) повинен бути відправлений назад разом із інформацією про те, які пакети були втрачені, щоб оригінальний відправник міг повторно відправити втрачені пакети. Якщо я правильно пам'ятаю, навіть пакети ACK можуть потребувати підтвердження для належної надійності.


Приклад: Конференц-дзвінок Skype

Для конференц-дзвінка Skype неважливо забезпечити надійне надсилання / отримання всіх відео- та аудіоданих. У наші дні UDP чудово справляється з мінімізацією втрат пакету. Важливо знати, що в UDP абсолютно немає гарантії на те, чи передача пройшла успішно. Що стосується аудіо / відео даних у конференц-дзвінку, UDP є правильним вибором, тому що ми дбаємо більше про отримання даних у режимі реального часу (тобто останніх). Якщо тут і там втрачено кілька пакетів, це не перерве спілкування драматично.

Однак у конференц-дзвінку люди можуть надсилати чати (миттєві повідомлення) або надсилати файли. У цих випадках надійність є необхідною вимогою для того, щоб файли та повідомлення не були пошкоджені або втрачені. Для IM-пристроїв вам може не знадобитися стан підключення, який надає TCP. Протоколу посередника, такого як RUDP (надійний UDP), може бути достатньо. Однак для файлів може знадобитися стан зв'язку, який надає TCP.


Вибір з реалізації

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

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


1

Я помітив багато коментарів, де люди вважають, що пакети TCP більше, ніж пакети UDP. Не просто мені довіряйте, читайте документацію. Протокол такий: кілька байт для заголовка Ethernet (тип 2 байтів повідомлення, 48 бітний MAC, 6 байт) (для Wifi, заголовка може відрізнятися) 20 байт для IP 20 байт для TCP або UDP х байт для даних x діапазон від 0 до приблизно 1500 (див. MTU) Нарешті, контрольна сума, щоб переконатися, що в цьому пакеті Ethernet не сталося пошкодження.

TCP дозволяють надсилати більші "потокові" пакети приблизно 64K. Цей "великий" блок насправді рубається у багатьох менших пакетах Ethernet.


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