Dlaczego protokół UDP z niezawodnością (implementowany w warstwie aplikacji) nie zastępuje protokołu TCP?

25

TCP zapewnia niezawodność w warstwie transportowej, podczas gdy UDP nie. UDP jest więc szybki. Jednak protokół w warstwie aplikacji może implementować niezawodny mechanizm podczas korzystania z UDP.

W tym sensie, dlaczego UDP z niezawodnością (zaimplementowanym na warstwie aplikacji) nie zastępuje TCP w przypadku, gdy UDP jest szybszy niż TCP, a my potrzebujemy niezawodności?

mallea
źródło
6
Dlaczego każda aplikacja zapewnia własny mechanizm niezawodności, skoro może polegać na innym powszechnie dostępnym protokole, takim jak TCP?
Nakrule
14
i jak proponujesz wdrożenie niezawodności w warstwie aplikacji bez spowalniania stosu?
JFL
6
Ponieważ nagłówek UDP jest mniejszy niż nagłówek TCP, możemy skorzystać z rozmiaru danych. ” Problem polega na tym, że prawdopodobnie zjesz znaczną część ładunku UDP za pomocą nagłówków protokołu warstwy aplikacji, które zmniejszą użyteczną ilość danych w Ładunek UDP. Różnica między rozmiarem nagłówka TCP i UDP wynosi tylko 12 bajtów. Ponadto protokół UDP jest naprawdę zaprojektowany dla małych ładunków, np. 576 bajtów; pamiętaj, że UDP po prostu utraci datagramy, a im więcej danych w datagramie, tym więcej danych zostanie utraconych w przypadku utraty datagramu.
Ron Maupin
21
Przepełnienie stosu jest powszechne, gdy programiści próbują i bezskutecznie tworzą protokoły podobne do TCP przy użyciu UDP. Bardziej doświadczeni programiści każą im się poddać i po prostu używać TCP. Wszyscy myślą, że mogą wykonać lepszą pracę, ale jest to bardzo mało prawdopodobne.
Ron Maupin
11
Wiem, że to nie jest część twojego pytania bezpośrednio, ale jednym z powodów, dla których UDP może być lepszy, jest to, że możesz wdrożyć tylko potrzebne części niezawodnościowe. Dzięki TCP zyskujesz pewność w zakresie zamawiania i dostawy. Oznacza to, że TCP może mieć czkawkę podczas oczekiwania na wysłanie poprzedniej wiadomości. Dzięki UDP możesz zdecydować, że chcesz tylko dostarczyć, ale jeśli jakaś wiadomość dotrze do porządku, nie czekasz na brakujące, po prostu je odrzucasz. Pułapka, na którą wpadają ludzie, próbuje replikować TCP w 100%. W takim przypadku wystarczy użyć protokołu TCP.
William Mariager

Odpowiedzi:

47

TCP jest tak szybki, jak tylko możesz coś zrobić, dzięki swoim właściwościom niezawodnościowym. Jeśli potrzebujesz tylko, powiedzmy, sekwencjonowania i wykrywania błędów, możesz skonfigurować UDP tak, aby działał doskonale. Jest to podstawa dla większości protokołów w czasie rzeczywistym, takich jak transmisja głosu, wideo itp., W których opóźnienia i drgania są ważniejsze niż „bezwzględna” korekcja błędów.

Zasadniczo TCP twierdzi, że ostatecznie na jego strumieniach można polegać. Jak szybko to zależy od różnych timerów, prędkości itp. Czas potrzebny na rozwiązanie błędów może być nieprzewidywalny, ale podstawowe operacje są tak szybkie, jak to możliwe, gdy nie ma błędów. Jeśli system wie coś o prawdopodobnych rodzajach błędów, może być w stanie zrobić coś, co nie jest możliwe z TCP. Na przykład, jeśli błędy jednobitowe są szczególnie prawdopodobne, można zastosować kodowanie z korekcją błędów dla tych błędów bitów: jest to jednak znacznie lepiej zaimplementowane w warstwie łącza. Jako kolejny przykład, jeśli powszechne są krótkie impulsy utraty całego pakietu, można rozwiązać ten problem za pomocą wielu transmisji bez oczekiwania na utratę, ale oczywiście jest to kosztowne w przepustowości. Lub też spowalniaj prędkość, aż prawdopodobieństwo błędu będzie znikome: również kosztowne w przepustowości. Na końcu,

Jeśli chodzi o implementację, przekonasz się, że stulecia programistów zainwestowane w TCP sprawią, że będzie ono szybsze niż cokolwiek, na co ogólnie stać by było, a także bardziej niezawodne w mało znanych przypadkach.

TCP zapewnia: wszechobecną metodę łączenia (niezbędną tam, gdzie systemy komunikacyjne nie mają wspólnej kontroli), dającą niezawodny, uporządkowany (i deduplikowany), dwukierunkowy, okienkowy, bajtowy strumień z kontrolą przeciążenia w sieciach z wieloma przeskokami na dowolnych odległościach.

Jeśli aplikacja nie wymaga wszechobecności (oprogramowanie działa po obu stronach) lub nie potrzebuje wszystkich funkcji TCP, wiele osób z zyskiem korzysta z innych protokołów, często oprócz UDP. Przykłady obejmują TFTP (minimalistyczny, z naprawdę nieefektywną obsługą błędów, QUIC, który ma na celu zmniejszenie kosztów ogólnych (wciąż oznaczonych jako eksperymentalne), oraz biblioteki takie jak lidgren, które mają precyzyjną kontrolę nad tym, które funkcje niezawodności są wymagane. [Dzięki komentatorom. ]

jonathanjo
źródło
7
Niestandardowe protokoły „UDP z niezawodnością” są również niezwykle powszechne w grach wideo. Istnieje mnóstwo bibliotek sieciowych z różnymi implementacjami. Zwykle chcą, aby pakiety były zamawiane i mają korekcję błędów, bez potrzeby retransmisji utraconych pakietów (i odbierają opóźnienia wszystkich przyszłych pakietów).
BlueRaja - Danny Pflughoeft
Wygląda na to, że mówisz: „TCP jest optymalnym rozwiązaniem ogólnym, więc zapewnia jego natywną obsługę”. +1
ikegami
1
@ BlueRaja-DannyPflughoeft A czasem potrzebujesz niezawodnych nieuporządkowanych pakietów (np. Efektów wizualnych zastosowanych do pobliskich graczy).
user253751
@ BlueRaja-DannyPflughoeft, jeśli masz typową przykładową bibliotekę protokołów, chętnie dołączę do odpowiedzi
jonathanjo
1
@jonathanjo Jednym z nich jest lidgren , który obsługuje 5 różnych metod dostawy (przewiń w dół) . Unity i Unreal Engine mają również własne sieciowe interfejsy API zbudowane na szczycie UDP.
BlueRaja - Danny Pflughoeft
10

Niezawodność UDP może rzeczywiście zastąpić TCP. Mamy już przykład: nazywa się QUIC .

Z Wikipedii:

Wśród innych aplikacji QUIC poprawia wydajność zorientowanych na połączenie aplikacji internetowych, które obecnie używają TCP. Odbywa się to poprzez ustanowienie szeregu multipleksowanych połączeń między dwoma punktami końcowymi za pośrednictwem protokołu UDP (User Datagram Protocol).

Zaletą korzystania z UDP w porównaniu do tworzenia zupełnie nowego protokołu warstwy transportowej jest to, że routery i inne urządzenia sieciowe już to rozumieją.

Andrea Corbellini
źródło
QUIC ma nieco inną charakterystykę niż TCP. W niektórych scenariuszach (niezawodna sieć lub szyfrowanie nie jest potrzebne) tak naprawdę jest wolniej: quora.com/…
freakish
Możesz także dodać kanały danych WebRTC do listy korzystającej z UDP przez sctp. W rzeczywistości, gdy połączenia UDP między partnerami nie są możliwe, WebRTC przejdzie w tryb failover do TCP, pozostawiając zauważalny spadek wydajności.
JSON
@freakish slowder jest w tym przypadku uogólnieniem. Na przykład QUIC dodaje do pakietów dodatkowe dane, aby zmniejszyć retransmisję, co wpływa na przepustowość, ale nie opóźnienie.
JSON
4

Możesz użyć UDP do implementacji funkcjonalności TCP w warstwie aplikacji (niezawodność, zdolność adaptacji). Równie dobrze możesz użyć TCP, chyba że coś, czego twoja aplikacja naprawdę potrzebuje, nie może być zrobione z TCP. Jeśli sam zaimplementujesz te funkcje, prawdopodobnie skończysz znacznie gorzej niż z TCP. Dodatkowe obciążenie zmniejsza również ogólną wydajność.

TCP nie jest wolny - wymaga tylko uścisku dłoni przed transmisją i okna transmisji, aby dostosować się do kanału. Może bardzo dobrze kształtować swoją przepustowość do dostępnego kanału transmisyjnego i dostosowywać się do zmian w trakcie przepływu, z których wszystkie UDP nie mogą (same w sobie).

Jednak protokoły powyżej warstwy transportowej są tutaj nie na temat.

Zac67
źródło
3
„Możesz użyć UDP do zaimplementowania funkcjonalności TCP w warstwie aplikacji (niezawodność, adaptowalność)” - Wierzę, że praktycznie tak są już wdrożone QUIC, µTP i często SCTP. (Mimo to zwykle uważam je za znajdujące się w górnej połowie warstwy transportowej, a UDP w dolnej połowie.)
grawity
1
@grawity To zależy od twojego POV - z perspektywy aplikacji warstwa pośrednia jest przedłużeniem warstwy transportowej. Formalnie i z perspektywy sieci (urządzenia) jest to część warstwy aplikacji.
Zac67
4

W czystej sieci są dość równoważne. Zdarzają się przypadki, że TCP zawiesza się na pewien czas (ktoś widział, że ekran HTTP zawiesza się przy ładowaniu?), Ale nie dostarcza śmieci ani nie miesza pakietów i rzadko się całkowicie poddaje.

UDP może dać warstwie aplikacji większą kontrolę nad ruchem kosztem ogromnej ilości pracy.

Odpowiedź na twoje pytanie brzmi: czasami dzieje się tak. Gry wymagające niskiego opóźnienia często to właśnie robią. To dużo więcej pracy, ale warto dokładnie kontrolować, ile wybitnych pakietów możesz mieć i jak często są one ponawiane.

Ogólnie rzecz biorąc, różnica polega na tym, że TCP jest bardzo dobrą implementacją ogólnego przeznaczenia, ale istnieją konkretne cele, które UDP może zrobić, że TCP robi bardzo słabo lub wcale - na przykład:

  • NIGDY nie poddawaj się (w przypadku TCP połączenie czasami się zawiesza i musisz je przerwać i zrestartować)
  • Wysyłanie szybkiego strumienia pakietów, które nie wymagają odpowiedzi, a od czasu do czasu nie przeszkadza Ci brak niektórych (gdy ważny jest tylko najnowszy pakiet, pozostałe można odrzucić) - pomyśl o aktualizacjach pozycji gry - możesz dostać trochę „Skacz” zamiast każdego kroku, ale uzyskujesz ten sam wynik szybciej i bardziej niezawodnie.
  • Radzenie sobie z niepewnymi sieciami poprzez analizę spadków pakietów i dynamiczne zmienianie częstotliwości i szybkości ponownych prób - być może nawet maksymalnego rozmiaru pakietu.

Ale generalnie nie warto, TCP jest dość optymalny, więc po co zajmować się całą dodatkową pracą i dodać (dużą) szansę na dodanie błędów i luk w zabezpieczeniach?

Bill K.
źródło
3

UDP nie jest szybki, ponieważ jest to UDP. TCP nie jest wolny, ponieważ jest TCP.

Oba protokoły są zaprojektowane z pewnymi gwarancjami, a surowy TCP ma więcej gwarancji niż surowy UDP.

A ogólna zasada jest taka: ceną gwarancji jest wydajność .

Nic nie zabrania ci wdrażania gwarancji TCP przez UDP. Ale wtedy dostajesz więcej gwarancji, więc musisz zapłacić cenę. Dlatego zmniejszasz wydajność do TCP lub gorzej (z powodu narzutu UDP). Chyba że znasz lepszą implementację TCP, co jest mało prawdopodobne. A jeśli to zrobisz (mam nadzieję), ujawnisz to, a my przyspieszymy standardowy TCP. I jesteśmy z powrotem tam, gdzie zaczęliśmy. :)

Możesz także grać z tymi gwarancjami. Lekko zmodyfikuj to, nieznacznie zmodyfikuj to. A potem otrzymujesz protokół taki jak QUIC, który jest nad UDP i jest bardzo podobny do TCP + TLS. W wielu przypadkach jest szybszy niż TCP (chociaż zgodnie z tym artykułem opóźnienie do 5% i buforowanie do 15%, co IMO nie jest wielkim problemem), ale w niektórych scenariuszach (np. Niezawodna sieć lub brak potrzeby szyfrowania) tak naprawdę jest wolniej (patrz wyjaśnienie tutaj ).

Możesz także osłabić te gwarancje, a wtedy będzie to bardziej sensowne. Powiedzmy na przykład, że przesyłasz strumieniowo, więc stare pakiety nie są interesujące. Tylko najnowsze. Ale przeciążenie jest nadal ważne. Więc bierzesz pewne gwarancje z TCP, ale nie wszystkie. I tak, ludzie to robią (np. Gry w czasie rzeczywistym). Zapewnia to lepszą wydajność kosztem niektórych gwarancji.

kapryśny
źródło
1

Twój pomysł byłby dobry w kosmosie.

Prawidłowa odpowiedź to „to zależy” i „ponieważ mogłoby to uszkodzić sieć jako całość”. TCP / IP jest bardzo miły dla sieci i automatycznie dostosowuje się do odpowiedniej prędkości, aby był szybki, ale nie generuje ton pakietów zwrotnych ICMP.

Gdy router z niewystarczającą ilością pamięci RAM nagle otrzymuje wiele dowolnego rodzaju pakietu - powiedzmy od Tsunami, Bittorrenta lub FDT - upuszcza go i wysyła do nadawcy niewielki pakiet odrzucający awarię. Teraz twój serwer UDP musi śledzić i ponownie przesyłać tę część ręcznie. Niektóre routery ISP kształtują Bittorrenta, więc wiele to boli Tsunami?

Protokół Tsunami używa UDP z kanałem kontrolnym w TCP. http://tsunami-udp.sourceforge.net/ Znalazłem badanie, które pokazuje, że jest wolniejsze niż rzecz zwana FDT.

Legendarny protokół Fast Data Transfer (FDT) z CERN jest w stanie nasycić dowolną sieć przy użyciu wielu strumieni TCP. Prawdopodobnie jest szybszy, ponieważ powoduje mniej ponownych transmisji niż Tsunami, które zalewają sieć tak dużą ilością UDP, a niektóre z nich nie są w stanie przejść przez całą drogę.

UDP jest wykorzystywany przez niewiarygodne aplikacje: przesyłanie strumieniowe audio, wejście / aktualizacja gier IO, „ping” jest w rzeczywistości ICMP, ale nie jest gwarantowane, Bittorrent, mosh ssh jest bardzo responsywny, telefonia VOIP, multiemisja, DNS jest wysyłany przez UDP AFAIK. Wszystko, co nie przeszkadza w dziwnym brakującym pakiecie i może natychmiast „nadrobić”.

TCP / IP był naprawdę zabójczym wynalazkiem, który pozwolił twórcom aplikacji, więc po prostu ustaw i zapomnij. Gniazdo to para adresów IP i portów. Zostały zaprojektowane tak, aby można je było konfigurować i pozostawać przez wiele godzin, dni, a nawet tygodni bez ponownego łączenia. Poczta e-mail, sieć, IRC i dosłownie wszystkie aplikacje typu killer używają protokołu TCP. Ale możesz pobrać dziwne przerwy w pobieraniu, które nagle idą szybciej ... i w kosmosie połączenia mogą przekroczyć limit czasu, dzięki czemu transfery w stylu Tsunami są najlepsze do przesyłania plików międzygwiezdnych - możesz być na czymś !!

Dowód znajduje się w końcowych uwagach tego wyciągu z badań naukowych, które wspominają o rosnącej odległości, o której mówię na temat: kosmosu Od: https://uscholar.univie.ac.at/get/o:300623.pdf

Bez zatorów wydajność FDT i GridFTP z TCP jest wyższa niż Tsunami i UDT. Najwyższa wydajność FDT wynosi 2,34 Gb / s przy 1 ms RTT, ale szybko spada po 100 ms w porównaniu do GridFTP, który działa lepiej niż FDT, gdy łącze RTT jest dłuższe niż 100 ms. Co ciekawe, przepustowość Tsunami nie zmniejszyła się wraz ze wzrostem RTT, co pokazuje, że ma on najbardziej skuteczną kontrolę zatorów przy wzroście RTT.

Z drugiej strony ... istnieje protokół kosmiczny podobny do e-maila, który byłby lepszy dla przestrzeni kosmicznej. Aplikacje nie mogą mieć nic przeciwko limitom czasu, takim jak wieczność.

Tomachi
źródło
0

TCP! = UDP + Niezawodność

TCP to nie tylko UDP z dodatkową niezawodnością. TCP oferuje więcej funkcji niż tylko niezawodność. Możesz o nich przeczytać w wielu dokumentach RFC.

Każda z tych funkcji „mogłaby” zostać zaimplementowana w warstwie aplikacji. W końcu staje się punkt, w którym zaczynasz od nowa wymyślać koło.

Aby wymienić kilka funkcji, TCP ma ...

  • Tworzenie i zakańczanie połączeń: wykonuje uzgadnianie i zamykanie połączeń

  • Kontrola przepływu: zapewnia, że ​​nadawca i odbiorca przesyłają z szybkościami, z których oboje mogą obsłużyć szybkość transmisji danych.

  • Kontrola przeciążenia od końca do końca: umożliwia węzłom końcowym dławienie przepustowości w oparciu o straty. Przeczytaj o powolnym uruchomieniu, unikaniu zatorów i szybkim odzyskiwaniu.

Z mojego doświadczenia wynika, że ​​UDP jest używane, gdy szybkość stanowi problem z niezawodnością. Możesz dodać pewien poziom niezawodności na poziomie aplikacji, który nie jest w 100% tak niezawodny jak TCP. Na przykład, jeśli nadal chcesz uzyskać wysoką wydajność, możesz zaimplementować korekcję błędów przesyłania (FEC), w której dane są przesyłane więcej niż jeden raz. Nadal masz dobrą wydajność i pewien poziom niezawodności (zauważ całkiem niezawodność TCP) bez całego czatu chit, aby zgubić pakiety. Handel polega na tym, że zwiększa wykorzystanie sieci, ale może być odpowiedni do aplikacji w czasie rzeczywistym, takich jak gry lub streaming.

jaybers
źródło
Ostatecznie można opisać te dodatkowe funkcje jako dotyczące niezawodności.
user207421