Jak można polegać na UDP?

0

UDP:

• Nie gwarantuje dostarczenia pakietu.
• Może fragmentować pakiet.
• Może zmieniać kolejność pakietów.

Zgadza się?

Gdyby było powiedziane, że UDP nie gwarantuje dostarczenia pakietu, ale jeśli dostarczy to poprawny, to OK, to ja bym rozumiał.

Ale jeśli może fragmentować… I zmieniać kolejność… To ja przestaję rozumieć. Przecież w tych warunkach dane otrzymane przez UDP są bez znaczenia. Jeśli nie wiadomo, który fragment się otrzymało, ani w którym miejscu pakiet został podzielony, to jak można w jakikolwiek sposób ten pakiet interpretować? Chyba trzebaby zatrudnić AI z zaimplementowanym modułem układania puzzli.

PS. Tak, wiem, że pytanie jest z pewnością głupie. Ale dział odpowiedni na takie pytania chyba?

1

Pakiety IP nie gwarantują dostarczenia, ulegają fragmentacji i nie wiadomo w jakiej kolejności są dostarczane. A mimo wszytko to w pakietach IP są enkapsulowane segmenty TCP, który uważany jest za protokół "niezadowny".

De facto segmenty UDP są gołymi danymi z dodatkowym nagłówkiem zapakowane w pakiety IP.

Nad protokołem zawodnym da się zaimplementować protokół niezawodny. I tak TCP korzysta z numerów segmentów, trzy stopniowego negocjowania otwarcia i zamknięcia połączenia, potwierdzeń dostarczenia, retransmisji, unikania przeciążenia, etc. To dzięki takim mechanizmom da się zaimplementować protokół gwarantujący dostarczenie w odpowiedniej kolejności.

A jeszcze ważniejsze jest zdanie sobie sprawy:

  • Że nie każda aplikacja potrzebuje takiej gwarancji.
  • Gwarancje które daje TCP nie przekładają się nad gwarancje na poziomie aplikacji (bo jest to gwarancja na poziomie protokołu, wiesz, że dane dotarły, nie że zostały przetworzone).
1

Jakby to opisać… UDP jest trochę tak jak Poczta Polska w rzeczywistym świecie — przesyłka może nie dojść, może przyjść w złym stanie i jak wysyłasz więcej niż jedną, to mogą przyjść w innej kolejności. Ale to wszystko to są rzadkie zdarzenia, zazwyczaj wszystko idzie OK. W ogólności taka komunikacja jest oczywiście niewiarygodna… ale prawdę powiedziawszy, żadna nie jest 1(https://en.wikipedia.org/wiki/Two_Generals%27_Problem).

Trzeba wiedzieć, co i gdzie stosować. TCP wtedy, gdy bardzo chcesz mieć dane kompletne i we właściwej kolejności i jesteś w stanie poczekać na transmisję tyle, ile będzie trzeba, aż w końcu wszystko przyjdzie idealnie. UDP zaś wtedy, gdy wolisz machnąć ręką na opóźnione pakiety, bo już Cię nie interesują — na przykład przy streamowaniu audio/video lepiej jest zgubić parę klatek czy pokazać coś w złej kolejności, niż blokować całe połączenie i czekać na „zguby”. Innym zastosowaniem jest tworzenie swojego własnego protokołu sprawdzającego poprawność danych.

3

Po prostu w praktyce wychodzi tak, że w pewnych rodzajach transmisji nic się nie stanie, jak zgubisz nawet 1% pakietów. Odbiorca prawdopodobnie nie zauważy albo otrzymanie danych szybko będzie dla niego znacznie ważniejsze, niż ich dokładność. Przykładem takiej transmisji jest połączenie głosowe albo streaming video.

0

Brak gwarancji dostarczenia rozumiem. Brak gwarancji zachowania kolejności rozumiem.

To, co mnie najbardziej rusza, to brak gwarancji zachowania kolejności W POŁĄCZENIU Z ryzykiem fragmentacji. To sprawia, że nie rozumiem, jak można interpretować dane otrzymane po UDP.

1

Na wiarę. To wszystko to są bardzo rzadkie przypadki. Często na tyle rzadkie, że lepiej je zignorować i mieć sporadyczne błędy, niż używać bardziej pewnych rozwiązań i mieć zawsze opóźnienia.

Podobnie w komputerze używasz niemal na pewno „zwykłych” kości RAM, bez ECC. Nie boisz się? No może i boisz, ale wolisz to ryzyko od utraty wydajności.

1

W trywialnym przypadku sprawdzając sumę kontrolną pakietu (czy doszedł kompletny) i wyciągając z niego znacznik sekwencji (np. czas). A co z tymi danymi zrobisz, decyduje aplikacja :-)

4
kmph napisał(a):

To, co mnie najbardziej rusza, to brak gwarancji zachowania kolejności W POŁĄCZENIU Z ryzykiem fragmentacji. To sprawia, że nie rozumiem, jak można interpretować dane otrzymane po UDP.

Fragmentacja zachodzi na warstwie trzeciej, nie czwartej. Pojedynczy pakiet UDP nie będzie pofragmentowany gdy zostanie dostarczony do aplikacji.

Jeżeli fragment IP z pakietu UDP zostanie zgubiony, to cały pakiet UDP zostanie odrzucony. Co znaczy, że w praktyce nic nie otrzymasz albo otrzymasz cały pakiet, a nie jego część. Stos sieciowy poskłada Ci fragmentu z pakietu IP w twój pakiet UDP. Jeden write i read na deskryptorze socketu przekładna się na jeden pakiet (albo część pakietu jak bufor jest za mały). Dodatkowo masz gwarancję zachowania granicy pakietu, w przeciwieństwie do TCP, gdzie po prostu czytasz strumień danych.

Poza tym, większość sieci IP ma MTU ustawione na 1500 bajtów. Tzn pakiety do ~1400bajtów nie powinny być fragmntowane.

3
nalik napisał(a):

Nad protokołem zawodnym da się zaimplementować protokół niezawodny. I tak TCP korzysta z numerów segmentów, trzy stopniowego negocjowania otwarcia i zamknięcia połączenia, potwierdzeń dostarczenia, retransmisji, unikania przeciążenia, etc. To dzięki takim mechanizmom da się zaimplementować protokół gwarantujący dostarczenie w odpowiedniej kolejności.

TCP jest „niezawodny” na tej zasadzie, że albo transmisja jest bezbłędna, albo połączenie ulega zerwaniu. Czyli katastrofa. Trzeba połączenie nawiązać na nowo, a to trwa, i jeżeli mamy do czynienia z transmisją w czasie rzeczywistym i nie ma mowy o nadrabianiu strat, to dziura wychodzi większa niż chwilowe zaniki w UDP.

Pomyśl na przykład o rozmowie głosowej: co wolisz - „niezawodne” połączenie ale lagi i przerwy w transmisji rzędu całych sekund, czy drobne braki od czasu do czasu, może nawet niezauważalne?

Fragmentacja przy odpowiednio małych pakietach nie zachodzi. A zmianę kolejności pakietów też można olać: jest tak rzadkim zjawiskiem że można po prostu odrzucać pakiety które przyszły nie o swoim czasie.

UDP nie służy do niezawodnego przesyłania danych, służy do szybkiego przesyłania danych w sytuacji gdy 100% niezawodność nie jest potrzebna.

1 użytkowników online, w tym zalogowanych: 0, gości: 1