Nie, UDP wciąż jest lepszy pod względem opóźnień w wydajności i zawsze będzie szybszy, ze względu na filozofię dwóch protokołów - zakładając, że dane komunikacyjne zostały zaprojektowane z myślą o UDP lub innej komunikacji stratnej.
TCP tworzy abstrakcję, w której docierają wszystkie pakiety sieciowe i docierają w dokładnie takiej kolejności, w jakiej zostały wysłane. Aby zaimplementować taką abstrakcję na kanale stratnym, musi ona zaimplementować retransmisje i limity czasu, które pochłaniają czas. Jeśli wyślesz 2 aktualizacje przez TCP, a pakiet pierwszej aktualizacji zginie, nie zobaczysz drugiej aktualizacji, dopóki:
- Wykryto utratę pierwszej aktualizacji.
- Wymagana jest ponowna transmisja pierwszej aktualizacji.
- retransmisja dotarła i została przetworzona.
Nie ma znaczenia, jak szybko odbywa się to w TCP, ponieważ dzięki UDP po prostu odrzucasz pierwszą aktualizację i używasz teraz drugiej, nowszej. W przeciwieństwie do TCP, UDP nie gwarantuje, że wszystkie pakiety dotrą i nie gwarantuje, że dotrą w kolejności.
Wymaga to wysłania właściwego rodzaju danych i zaprojektowania komunikacji w taki sposób, aby utrata danych była możliwa do zaakceptowania.
Jeśli masz dane, do których musi dotrzeć każdy pakiet, a Twoja gra musi przetwarzać pakiety w kolejności, w jakiej zostały wysłane, UDP nie będzie szybsze. W rzeczywistości użycie UDP w tym przypadku byłoby prawdopodobnie wolniejsze, ponieważ rekonstruujesz TCP i implementujesz go za pomocą UDP, w którym to przypadku równie dobrze możesz użyć TCP.
EDYCJA - Dodanie dodatkowych informacji w celu włączenia / rozwiązania niektórych komentarzy:
Zwykle wskaźnik utraty pakietów w sieci Ethernet jest bardzo niski, ale staje się znacznie wyższy po włączeniu Wi-Fi lub w trakcie przesyłania / pobierania przez użytkownika. Załóżmy, że mamy idealnie jednolitą utratę pakietów wynoszącą 0,01% (w jedną stronę, a nie w obie strony). W strzelankach FPS klienci powinni wysyłać aktualizacje za każdym razem, gdy coś się stanie, na przykład gdy kursor myszy obróci odtwarzacz, co dzieje się około 20 razy na sekundę. Mogą także wysyłać aktualizacje na ramkę lub w ustalonych odstępach czasu, co będzie wynosić 60-120 aktualizacji na sekundę. Ponieważ aktualizacje te są wysyłane w różnych momentach, będą / powinny być wysyłane w jednym pakiecie na aktualizację. W grze 16-osobowej wszyscy 16 graczy wysyła te 20-120 pakietów na sekundę do serwera, co daje w sumie 320-1920 pakietów na sekundę. Przy naszym współczynniku utraty pakietów wynoszącym 0,01% spodziewamy się utraty pakietu co 5,2-31,25 sekundy.
Na każdym pakiecie, który otrzymamy po zgubionym pakiecie, wyślemy DupAck, a po 3. DupAck nadawca ponownie wyśle utracony pakiet . Tak więc czas wymagany przez TCP do zainicjowania retransmisji wynosi 3 pakiety, plus czas, jaki musi upłynąć, zanim ostatni dupAck dotrze do nadawcy. Następnie musimy poczekać, aż nadejdzie retransmisja, więc w sumie czekamy 3 pakiety + 1 opóźnienie w obie strony. Opóźnienie w obie strony wynosi zwykle 0-1 ms w sieci lokalnej i 50-200 ms w Internecie. 3 pakiety zwykle docierają w ciągu 25 ms, jeśli wyślemy 120 pakietów na sekundę, i w 150 ms, jeśli wyślemy 20 pakietów na sekundę.
W przeciwieństwie do UDP, odzyskujemy utracony pakiet, gdy tylko otrzymamy następny pakiet, więc tracimy 8,3 ms, jeśli wysyłamy 120 pakietów na sekundę, i 50 ms, jeśli wysyłamy 20 pakietów na sekundę.
W przypadku protokołu TCP sytuacja staje się coraz bardziej skomplikowana, jeśli musimy również rozważyć Nagle (jeśli programista zapomni wyłączyć wysyłanie koalescencji lub nie może wyłączyć opóźnionego potwierdzenia ACK ), unikania przeciążenia sieci lub jeśli utrata pakietów jest na tyle poważna, że musimy uwzględnić wiele straty pakietów (w tym utracone Ack i DupAck). Dzięki UDP możemy łatwo pisać szybszy kod, ponieważ po prostu nie dbamy o to, aby być dobrym obywatelem sieci, tak jak TCP.