Jeśli masz sytuację, w której połączenie TCP jest potencjalnie zbyt wolne, a „połączenie” UDP jest potencjalnie zbyt zawodne, czego używasz? Istnieją różne standardowe niezawodne protokoły UDP, jakie masz z nimi doświadczenia?
Proszę omówić jeden protokół dla każdej odpowiedzi, a jeśli ktoś już wspomniał o tym, z którego korzystasz, rozważ głosowanie i użycie komentarza do opracowania, jeśli to konieczne.
Interesują mnie różne opcje, z których TCP znajduje się na jednym końcu skali, a UDP na drugim. Dostępne są różne niezawodne opcje UDP, z których każda przenosi niektóre elementy protokołu TCP do UDP.
Wiem, że często TCP jest właściwym wyborem, ale posiadanie listy alternatyw często pomaga dojść do takiego wniosku. Rzeczy takie jak Enet, RUDP itp., Które są zbudowane na UDP, mają różne zalety i wady, czy z nich korzystałeś, jakie masz doświadczenia?
Aby uniknąć wątpliwości, nie ma więcej informacji, jest to pytanie hipotetyczne i miałem nadzieję, że przyniesie listę odpowiedzi, które wyszczególniają różne opcje i alternatywy dostępne dla kogoś, kto musi podjąć decyzję.
źródło
Odpowiedzi:
Trudno odpowiedzieć na to pytanie bez dodatkowych informacji o domenie problemu. Na przykład, jakiej ilości danych używasz? Jak często? Jaki jest charakter danych? (np. czy są to niepowtarzalne, jednorazowe dane? Czy jest to strumień przykładowych danych? itp.) Dla jakiej platformy projektujesz? (np. komputer stacjonarny / serwer / urządzenie wbudowane) Aby określić, co rozumiesz przez „zbyt wolno”, jakiego medium sieciowego używasz?
Ale w (bardzo!) Kategoriach ogólnych myślę, że będziesz musiał bardzo się postarać, aby pokonać tcp dla szybkości, chyba że możesz poczynić twarde założenia dotyczące danych, które próbujesz wysłać.
Na przykład, jeśli dane, które próbujesz wysłać, są takie, że możesz tolerować utratę pojedynczego pakietu (np. Regularnie próbkowane dane, w których częstotliwość próbkowania jest wielokrotnie wyższa niż szerokość pasma sygnału), prawdopodobnie możesz poświęcić pewną niezawodność transmisji, upewniając się, że można wykryć uszkodzenie danych (np. za pomocą dobrego CRC)
Ale jeśli nie możesz tolerować utraty pojedynczego pakietu, będziesz musiał zacząć wprowadzać typy technik zapewniających niezawodność, które już posiada tcp. I bez wkładania rozsądnej ilości pracy może się okazać, że zaczynasz budować te elementy w rozwiązanie przestrzeni użytkownika ze wszystkimi nieodłącznymi problemami z szybkością.
źródło
A co z SCTP . Jest to standardowy protokół IETF (RFC 4960)
Ma zdolność kruszenia, która może pomóc w zwiększeniu szybkości.
Aktualizacja: porównanie między TCP i SCTP pokazuje, że wydajności są porównywalne, chyba że można użyć dwóch interfejsów.
Aktualizacja: ładny artykuł wprowadzający .
źródło
ENET - http://enet.bespin.org/
Pracowałem z ENET jako niezawodnym protokołem UDP i napisałem wersję przyjazną dla gniazd asynchronicznych dla mojego klienta, który używa go na swoich serwerach. Działa całkiem nieźle, ale nie podoba mi się narzut, jaki pingowanie peer to peer dodaje do bezczynnych połączeń; gdy masz dużo połączeń, regularne pingowanie wszystkich z nich jest bardzo pracochłonne.
ENET daje możliwość wysyłania wielu „kanałów” danych, a wysyłane dane są zawodne, wiarygodne lub sekwencjonowane. Obejmuje również wspomniany wcześniej ping peer to peer, który działa jak utrzymywanie przy życiu.
źródło
Mamy kilku klientów z branży obronnej, którzy używają UDT (transfer danych oparty na UDP) (patrz http://udt.sourceforge.net/ ) i jesteśmy z niego bardzo zadowoleni. Widzę, że ma również przyjazną licencję BSD.
źródło
RUDP - niezawodny protokół datagramów użytkownika
Zapewnia to:
Wydaje się, że jest nieco bardziej konfigurowalny pod względem utrzymania przy życiu niż ENet, ale nie daje tak wielu opcji (tj. Wszystkie dane są wiarygodne i sekwencjonowane, a nie tylko bity, które zdecydujesz, że powinny być). Wdrożenie wydaje się dość proste.
źródło
Jak zauważyli inni, twoje pytanie jest bardzo ogólne i to, czy coś jest „szybsze” niż TCP, zależy w dużej mierze od typu aplikacji.
Protokół TCP jest generalnie tak szybki, jak to tylko możliwe, aby zapewnić niezawodne przesyłanie strumieniowe danych z jednego hosta do drugiego. Jeśli jednak aplikacja wykonuje dużo małych serii ruchu i czeka na odpowiedzi, bardziej odpowiedni może być protokół UDP, aby zminimalizować opóźnienia.
Jest łatwy środek. Algorytm Nagle jest częścią protokołu TCP, która pomaga zapewnić, że nadawca nie przytłoczy odbiornika dużego strumienia danych, powodując przeciążenie i utratę pakietów.
Jeśli potrzebujesz niezawodnego dostarczania w kolejności protokołu TCP, a także szybkiej odpowiedzi protokołu UDP i nie musisz martwić się o przeciążenie spowodowane wysyłaniem dużych strumieni danych, możesz wyłączyć algorytm Nagle:
źródło
Każdy, kto zdecyduje, że powyższa lista nie wystarczy i że chce opracować swój własny niezawodny UDP, zdecydowanie powinien zapoznać się ze specyfikacją Google QUIC, ponieważ obejmuje ona wiele skomplikowanych przypadków narożnych i potencjalnych ataków typu „odmowa usługi”. Nie bawiłem się jeszcze implementacją tego i możesz nie chcieć lub potrzebować wszystkiego, co zapewnia, ale dokument jest wart przeczytania przed rozpoczęciem nowego, „niezawodnego” projektu UDP.
Dobry punkt wyjścia do QUIC jest tutaj , na blogu Chromium.
Aktualny dokument projektowy QUIC można znaleźć tutaj .
źródło
Kluczowym słowem w Twoim zdaniu jest „potencjalnie”. Myślę, że naprawdę musisz udowodnić sobie, że TCP jest w rzeczywistości zbyt wolny dla twoich potrzeb, jeśli potrzebujesz niezawodności w swoim protokole.
Jeśli chcesz uzyskać niezawodność z UDP, w zasadzie zamierzasz ponownie zaimplementować niektóre funkcje TCP oprócz UDP, co prawdopodobnie spowoduje, że wszystko będzie wolniejsze niż po prostu używanie TCP w pierwszej kolejności.
źródło
Protokół DCCP, znormalizowany w RFC 4340 , „Datagram Congestion Control Protocol” może być tym, czego szukasz.
Wydaje się, że jest zaimplementowany w systemie Linux .
źródło
Może to być RFC 5405 , „Wytyczne dotyczące używania Unicast UDP dla projektantów aplikacji”.
źródło
Czy rozważałeś kompresję danych?
Jak wspomniano powyżej, brakuje nam informacji o dokładnym charakterze problemu, ale kompresja danych w celu ich przeniesienia może pomóc.
źródło
RUDP . Wiele serwerów z gniazdami do gier implementuje coś podobnego.
źródło
Najlepszym sposobem na osiągnięcie niezawodności przy użyciu UDP jest zbudowanie niezawodności w samej aplikacji (na przykład poprzez dodanie mechanizmów potwierdzania i retransmisji)
źródło