UDP è ancora meglio di TCP per i giochi in tempo reale ricchi di dati?


71

So che UDP è di solito raccomandato per giochi multiplayer in tempo reale con un elevato utilizzo dei dati.

La maggior parte degli articoli ha anni di servizio e dal momento che circa l'80% di tutti i dati trasmessi su Internet è TCP, per TCP deve essere stata fatta molta ottimizzazione.

Questo mi chiedo: UDP è ancora superiore in termini di velocità e latenza? Le recenti ottimizzazioni TCP potrebbero rendere le prestazioni TCP migliori di UDP?


25
Con UDP non esiste alcuna garanzia che i pacchetti vengano ricevuti o addirittura ordinati, il che da solo rende UDP più veloce di TCP.
Nathan,

4
@KaareZ cosa intendi più velocemente per implementare?
Nathan,

2
@nathan È più semplice sviluppare la tua applicazione con TCP che UDP. Voglio sapere se tutte le ottimizzazioni TCP hanno reso TCP un'opzione migliore in termini di prestazioni.
KaareZ,

3
@KaareZ Non sono un esperto, ma pensiamoci. In che modo TCP può essere migliore in termini di prestazioni ed essere comunque un protocollo affidabile? Non puoi avere tutto. TCP è fatto per affidabilità. La vera domanda è: perché vorresti usare TCP nel tuo gioco?
Nathan,

7
UDP è migliore di TCP se e solo se si è in grado (= esperto programmatore di rete di basso livello) di implementare in modo efficace solo le funzionalità TCP necessarie al suo interno. Eliminazione delle funzionalità TCP non necessarie per le prestazioni.
Wondra,

Risposte:


119

No, UDP è ancora superiore in termini di latenza delle prestazioni e sarà sempre più veloce, a causa della filosofia dei 2 protocolli, supponendo che i dati di comunicazione siano stati progettati tenendo conto di UDP o di qualsiasi altra comunicazione con perdita di dati.

TCP crea un'astrazione in cui arrivano tutti i pacchetti di rete e arrivano nell'ordine esatto in cui sono stati inviati. Per implementare tale astrazione su un canale con perdite, è necessario implementare ritrasmissioni e timeout, che richiedono tempo. Se invii 2 aggiornamenti su TCP e un pacchetto del primo aggiornamento viene perso, non vedrai il secondo aggiornamento fino a quando:

  1. Viene rilevata la perdita del primo aggiornamento.
  2. È richiesta una ritrasmissione del primo aggiornamento.
  3. la ritrasmissione è arrivata ed è stata elaborata.

Non importa quanto velocemente ciò avvenga in TCP, perché con UDP scarti semplicemente il primo aggiornamento e usi subito il secondo, il più recente. A differenza di TCP, UDP non garantisce l'arrivo di tutti i pacchetti e non garantisce l'arrivo in ordine.

Ciò richiede di inviare il giusto tipo di dati e di progettare la propria comunicazione in modo tale che la perdita di dati sia accettabile.

Se disponi di dati in cui deve arrivare ogni pacchetto e i pacchetti devono essere elaborati dal tuo gioco nell'ordine in cui sono stati inviati, UDP non sarà più veloce. In effetti, l'utilizzo di UDP in questo caso sarebbe probabilmente più lento perché stai ricostruendo TCP e lo stai implementando tramite UDP, nel qual caso potresti anche usare TCP.

MODIFICA - Aggiunta di alcune informazioni aggiuntive per incorporare / indirizzare alcuni dei commenti:

Normalmente, il tasso di perdita di pacchetti su Ethernet è molto basso, ma diventa molto più alto quando è coinvolto il WiFi o se l'utente ha un upload / download in corso. Supponiamo di avere una perdita di pacchetti perfettamente uniforme dello 0,01% (solo andata, non andata e ritorno). Su uno sparatutto in prima persona, i clienti devono inviare aggiornamenti ogni volta che succede qualcosa, come quando il cursore del mouse gira il giocatore, cosa che accade circa 20 volte al secondo. Potrebbero anche inviare aggiornamenti per frame o ad intervalli fissi, che sarebbero 60-120 aggiornamenti al secondo. Poiché questi aggiornamenti vengono inviati in momenti diversi, verranno / dovrebbero essere inviati in un pacchetto per aggiornamento. In una partita a 16 giocatori, tutti e 16 i giocatori inviano questi 20-120 pacchetti al secondo al server, per un totale di 320-1920 pacchetti al secondo. Con il nostro tasso di perdita di pacchetti dello 0,01%, prevediamo di perdere un pacchetto ogni 5,2-31,25 secondi.

Su ogni pacchetto che riceviamo dopo il pacchetto perso, invieremo un DupAck e dopo il terzo DupAck il mittente ritrasmetterà il pacchetto perso . Quindi il tempo richiesto da TCP per avviare la ritrasmissione è di 3 pacchetti, più il tempo impiegato dall'ultimo DupAck per arrivare al mittente. Quindi dobbiamo attendere l'arrivo della ritrasmissione, quindi in totale aspettiamo 3 pacchetti + 1 latenza andata e ritorno. La latenza di andata e ritorno è in genere 0-1 ms su una rete locale e 50-200 ms su Internet. In genere, 3 pacchetti arriveranno in 25 ms se inviamo 120 pacchetti al secondo e in 150 ms se inviamo 20 pacchetti al secondo.

Al contrario, con UDP ci riprendiamo da un pacchetto perso non appena otteniamo il pacchetto successivo, quindi perdiamo 8,3 ms se inviamo 120 pacchetti al secondo e 50 ms se inviamo 20 pacchetti al secondo.

Con TCP le cose diventano più complicate se dobbiamo anche considerare Nagle (se lo sviluppatore dimentica di disattivare l'invio di coalescenza o non può disabilitare l'ACK ritardato ), l'evitamento della congestione della rete o se la perdita di pacchetti è abbastanza grave che dobbiamo tenere conto di più perdite di pacchetti (inclusi Ack e DupAck persi). Con UDP possiamo facilmente scrivere codice più veloce perché semplicemente non ci interessa essere un buon cittadino di rete come fa TCP.


Nota: UDP può trasmettere la rete locale (possibile vantaggio) e poiché Vista richiede che l'amministratore esegua il server / trasmette su UDP (svantaggio) (UAC / firewall tendono a non riuscire a informare l'azione dell'utente).
PTwr

7
"Se invii 2 aggiornamenti su TCP e un pacchetto del primo aggiornamento viene perso" Vero, ma quali sono le possibilità che ciò accada? Secondo pingman : "Qualsiasi perdita di pacchetti superiore al 2% in un periodo di tempo è un forte indicatore di problemi".
mucaho,

30
@Peter stai dimenticando che in TCP ogni pacchetto eliminato blocca ogni pacchetto successivo. Con un ping di 100ms potrebbero essere facilmente 300-500ms prima che quel pacchetto venga ritrasmesso e ricevuto, quindi sono 6-10 pacchetti che vengono bloccati ogni 33 secondi. Ciò sarà sicuramente evidente in un FPS simile a un terremoto.
BlueRaja - Danny Pflughoeft,

12
In molte implementazioni TCP, il primo timeout dopo un mancato riconoscimento richiederà un secondo intero. Questo è tanto tempo. Se i pacchetti sono piccoli, UDP potrebbe facilmente smussare una o due trasmissioni perse semplicemente facendo in modo che ciascun pacchetto includa i dati degli ultimi due aggiornamenti in modo che l'applicazione ottenga i dati necessari prima che il mittente o il destinatario possano sapere che il primo pacchetto è scomparso.
supercat,

23
Con un gioco come Quake, perdere il primo pacchetto è irrilevante. In FAR meno di tempo ci vorrebbe per rilevare la perdita e ritrasmettere il primo pacchetto, dovresti aver già trasmesso un secondo pacchetto che rende comunque il primo obsoleto. Questo è lo stesso motivo per cui molte applicazioni voce e video in tempo reale usano anche UDP. Se un pacchetto viene eliminato, preferiresti perdere solo 0,02 secondi di audio piuttosto che ritardare l'intero flusso di almeno un secondo o più. Lo stesso è generalmente vero con i giochi in tempo reale, poiché vuoi sapere dove si trova un oggetto ora , non 1,5 secondi fa.
reirab

19

Siamo d'accordo sul fatto che sia TCP che UDP siano protocolli basati sull'IP , no? IP specifica il modo in cui i messaggi vengono recapitati su Internet, ma nulla riguarda la struttura, il formato dei messaggi. Ecco i protocolli TCP e UDP. Usano le proprietà IP, ma consentono al programmatore di concentrarsi sullo scambio di messaggi senza preoccuparsi degli strati inferiori della comunicazione in rete. Ed è fantastico, perché trattare direttamente i segnali analogici nei fili sarebbe un po 'doloroso.

  • TCP fornisce una serie di funzioni per inviare e ricevere messaggi. Divide i nostri dati in piccoli pacchetti per noi stessi e li invia attraverso la rete. Tutto ciò che ci viene chiesto è una porta da utilizzare per il socket di rete e il messaggio effettivo che vogliamo inviare. Inoltre, è affidabile, il che significa che se alcuni pacchetti vengono persi lungo la rete vengono rilevati, quindi inviati di nuovo avendo cura di inviarli nello stesso ordine in cui dovevano arrivare.

  • D'altro canto, UDP è un protocollo orientato al controllo dell'utente. Quando si utilizza UDP per inviare i nostri datagrammi , non possiamo essere sicuri che il datagramma arrivi mai a destinazione o meno (e intendiamo qui certezza matematica: quando inviamo un pacchetto probabilmente arriverà, ma non possiamo essere sicuri di 100%). Inoltre, quando un pacchetto viene perso, non verrà né rilevato né inviato di nuovo.

A questo punto, TCP sembrerebbe la soluzione ideale per tutti i nostri problemi. È affidabile, è veloce, risolve la latenza della connessione per noi tenendo traccia di quali pacchetti sono arrivati ​​e quali pacchetti dobbiamo ancora inviare.

MA , guarda oltre. L'unico vantaggio che UDP ci offre è la sua velocità, ed è proprio l'unica cosa che vogliamo davvero. Un pacchetto UDP è appena creato, verificato e inviato senza particolari controlli, perché funziona così il protocollo UDP. Un pacchetto TCP deve essere creato, etichettato, sommato e quando arriva un ACK viene rispedito per dire al mittente "il pacchetto x è qui, continua" , e quando questo segnale non viene inviato significa che tale pacchetto x deve essere inviato ancora.

So che UDP è di solito raccomandato per giochi multiplayer in tempo reale con un elevato utilizzo dei dati.

Sì, ma non solo. UDP è ampiamente preferito su TCP principalmente perché la sua alta velocità è idea per gestire l'invio e la gestione di dati elevati. Ciò accade quando, supponendo che tale videogioco sia eseguito su blocco deterministico (ciò che accade sul server viene replicato in modo identico su qualsiasi client indipendentemente dalla latenza della rete), un pacchetto di aggiornamento viene perso e non arriva mai a destinazione. TCP rinvia nuovamente tale pacchetto e i seguenti pacchetti vengono eliminati perché non arrivano in ordine e vengono quindi rispediti dopo quello perso. UDP è molto più tollerante in questo scenario: non si preoccuperà di questo pacchetto, perché stanno arrivando nuovi aggiornamenti. L'aggiornamento perso non viene visualizzato, invece la fisica del gioco viene interpolata in base al metodo di integrazione utilizzato e all'ultimo aggiornamento ricevuto.

TCP provoca il jitter quando la latenza è abbastanza alta, UDP non:

<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>

Questo mi chiedo se UDP sia ancora superiore in termini di velocità e latenza.

Bene, sì, lo è e lo sarà per molto tempo. Puoi leggere di più su TCP vs UDP qui .


8
TCP utilizza flussi di byte anziché datagrammi. UDP utilizza datagrammi. Le buone implementazioni TCP manterranno i pacchetti che arrivano fuori servizio, ma nessun contenuto dei pacchetti può essere reso disponibile per l'applicazione a meno che o fino a quando non sono stati ricevuti tutti i pacchetti precedenti. Pertanto, se un pacchetto viene perso, il mittente potrebbe non aver bisogno di ritrasmettere tutto ciò che seguiva il pacchetto perso, ma l'applicazione ricevente non vedrebbe nulla oltre il pacchetto perso fino a quando quel pacchetto non viene ritrasmesso (al che l'applicazione visualizzerebbe immediatamente il contenuto di quello pacchetto e quelli successivi).
supercat,

@supercat Sfortunatamente, TCP non ha alcun modo per dire esattamente al mittente quali pacchetti ha ricevuto e non ricevuto. Ha solo un meccanismo per "Ho ricevuto tutti i byte fino al numero di sequenza x". Se il mittente ritrasmette i pacchetti già ricevuti dal destinatario, ignorerà semplicemente le copie.
reirab

@reirab: ho pensato che esistessero alcune estensioni moderne che includevano quella funzionalità, anche se anche senza quello penso che un'implementazione che aveva inviato un dato fino a byte # 1.050.000 ma che aveva ricevuto solo ack per dati fino a 1.000.000 sarebbe, dopo un secondo senza sentire per qualsiasi cosa oltre 1.000.000, iniziare inviando un blocco di dati da 1.000.000 a 1.000.500 circa e quindi in attesa di una risposta. Se ottiene un riscontro per dati fino a 1.000.500, può quindi ritrasmettere più dati; se ottiene un riscontro per dati fino a 1.050.000, può saltare le ritrasmissioni.
supercat,

1
@Giorgio IP non specifica nulla dei segnali analogici. Questo è fatto a livello fisico. IP opera due livelli sopra quello a livello di rete. All'IP non potrebbe importare di meno se i bit passano su fibra, un collegamento satellitare o un modem dial-up da 14,4 kbps. UDP e TCP sono un livello dall'IP, al livello di trasporto. Inoltre, come dice Supercat, TCP presenta un'interfaccia di flusso per l'applicazione, non un'interfaccia di datagramma come UDP.
reirab

@supercat Hmm ... potresti avere ragione sulle estensioni moderne, anche se certamente non fa parte dello standard TCP originale. Un ACK ha solo un numero progressivo. Suppongo che un'implementazione TCP normalmente inizierebbe a ritrasmettere l'intera finestra di invio se un pacchetto viene eliminato anziché attendere un intero RTT per ciascun pacchetto. Ciò aggiungerebbe un'enorme quantità di latenza se si perdessero diversi pacchetti consecutivi per un guadagno molto ridotto.
reirab

9

TCP <- Transmission Control Protocol. È fatto per controllare la trasmissione.

TCP è stato creato per essere un buon cittadino di rete diplomatico. Si concentra sul rendere il networking una buona esperienza per tutti e diminuisce volentieri il throughput per raggiungere questo obiettivo. Si adatta all'ambiente aggiungendo latenza . I motivi sono ad esempio:

  • Il ricevitore rileva un pacchetto mancante, dice al mittente di rallentare (dimezzare la velocità per un po ').
  • Il ricevitore rileva un ordine di pacchetti in entrata errato (forse hanno preso diversi percorsi di rete), dice al mittente di rallentare - e tra l'altro, il ricevitore non accetterà ulteriori pacchetti finché non arriva quello mancante. Per far fronte a ciò ci vuole tempo.
  • Il mittente rileva la congestione della rete (ad es. Tempo di andata e ritorno lento), aggiunge la latenza.
  • Il ricevitore non riesce a tenere il passo con la velocità (il buffer di input sta diventando troppo pieno), chiede al mittente di aggiungere la latenza (controllo del flusso).
  • C'è un singolo ricevitore lento (high ping bastard, crybaby, come si chiamano) tra i ricevitori, latenza (può essere) aggiunta in casa.

Inoltre

  • L'algoritmo di Nagle può tenere in sospeso i dati dei mittenti, fino a quando non c'è altro da inviare (al fine di utilizzare i frame di dati in modo più efficiente). I dati temporali vengono ritardati.
  • Credo che i normali router domestici con wlan possano fare cose intelligenti (rallentare) per rendere più fluido il throughput TCP tra più client (l'interfaccia wlan è il collo di bottiglia, anche se il gioco non lo utilizza). Relativo alla trasmissione / multicasting, ad es. "altri" dati possono ridurre il throughput TCP.
  • TCP ACK riconosce tutto ciò che non è necessario per un ambiente di gioco. Non ha senso ACKare ogni singolo aggiornamento di fisica. Abbastanza per riconoscere, ad esempio, una volta al secondo o in modo simile. Se un client (o un server) rimane in silenzio per un tempo più lungo, è il momento di reagire.

Nonostante ciò, TCP fornisce la cifra più alta per (dati trasmessi complessivi) / (tempo complessivo consumato). Solo che non succede proprio quando vuoi che accada.

UDP non fa nessuno di questi. Spara sulla tua volontà, solo che non ci si può aspettare che colpisca ogni volta - invece il bersaglio deve annunciare che "non hai sparato da molto tempo, perché?". È ancora possibile creare pacchetti ACK personalizzati, inserire più record in un singolo pacchetto, ecc. Inoltre, è importante controllare l'attraversamento NAT. UDP è sicuramente adatto a giochi con bassa richiesta di latenza.


1
Nota: l'algoritmo di Nagle può essere disabilitato, ad esempio per Linux .
mucaho,

Nagle può funzionare contro (e può essere evitato impostando ogni pacchetto su "push" dall'applicazione) mentre Delayed Ack funziona a favore di TCP, consente al mittente di inserire più byte sul filo fino a quando la finestra di invio è piena (idealmente grande poiché il buffer di ricezione si trova dall'altra parte) indipendentemente dal fatto che sia stato visto un ack.
Jeff Meden,

4
È il protocollo di controllo della trasmissione .
ysdx,

1
Digita queste parole un milione di volte ... grazie - risolto.
Stormwind,

3

È possibile confrontare il primo diagramma di RFC 768 (UDP) con il primo diagramma di RFCP 793 (TCP) pagina 15 .

Entrambi mostrano 16 bit per una "porta di origine" seguiti da 16 bit per una "porta di destinazione". Entrambi mostrano 16 bit per un "checksum". Secondo RFC 768, la "procedura di checksum di UDP è la stessa utilizzata in TCP".

Mentre la lunghezza di UDP racchiude i dettagli del diagramma di UDP, la lunghezza di TCP fa parte di un "pseudo header a 96 bit" descritto a pagina 15 e 16.

Non aspettarti che TCP superi le prestazioni di UDP. Questo semplicemente non è probabile che accada, per diversi motivi. Uno è che TCP ha semplicemente più bit. Pertanto, se le apparecchiature sono in grado di elaborare efficacemente un determinato numero di bit al secondo, ciò consentirà un numero maggiore di pacchetti UDP rispetto ai pacchetti TCP.

L'altro motivo è che la "stretta di mano a tre vie" di TCP significa che il mittente deve attendere una risposta. Questo requisito introduce un sovraccarico aggiuntivo che UDP non gestisce. C'è un motivo per cui la maggior parte delle comunicazioni Internet iniziano con alcune comunicazioni UDP. Il DNS di base utilizza UDP perché una richiesta e una risposta possono essere completate in meno passaggi rispetto al processo di "handshake a tre vie" di TCP. La funzionalità TCP di tenere traccia dei pacchetti persi è piuttosto poco entusiasmante, poiché un computer potrebbe semplicemente effettuare una nuova richiesta anziché cercare di far sapere a un sistema remoto che esiste una richiesta precedente non soddisfatta.


Anche se i riassunti in inglese (come si vede in altre risposte) sono carini, avere delle descrizioni accurate e precise può essere più semplice.
TOOGAM,

Intendi 16 bit, non byte!
Jcaron,

Oh, sciocco me. è un esempio del perché le risposte tecnicamente precise sono buone; sono facili da identificare errori e vedere le informazioni corrette. Ho risolto la risposta. Grazie @jcaron
TOOGAM

2

Considera cosa sta succedendo per un momento. Per semplificare gli scenari, hai due opzioni quando provi a inviare un cambio di stato (come il tuo giocatore ha appena cambiato direzione, o ha sparato con una pistola, o qualche altro giocatore ha appena lanciato una bomba):

  1. Tieni aperta una sessione TCP e quando la bomba esplode invia un messaggio TCP a tutti i giocatori (se possibile, vedi sotto)
  2. Mantieni una porta UDP in ascolto e quando la bomba deve esplodere invia un messaggio UDP a tutti i giocatori, indipendentemente dal loro stato di connessione

Supponendo che non fosse necessario un aggiornamento prima, il momento in cui quel singolare aggiornamento arriva in 1 vs 2 non sarà molto diverso. È un viaggio dal server al client. Ma, diciamo invece di far esplodere solo una bomba, stai provando a trasmettere continuamente l'attività di qualcuno che corre attraverso un labirinto; tessitura, anatra, tiro, ecc. Nel caso di UDP, ogni azione verrà inviata in un datagramma, non appena accade. Nel caso di TCP ogni azione verrà inviata in un pacchetto solo se il server è autorizzato a inviare. Cosa dice che è consentito inviare? Avere spazio nella finestra TCP (supponendo che l'attivazione ritardata sia attiva) in modo che il messaggio possa essere inserito sul filo. In caso contrario, deve attendere che arrivi un client dal client prima di inviarlo.

Quanto lungo è troppo lungo? Quando lo sviluppo di sparatutto in prima persona multiplayer ha colpito, è tornato indietro alla fine degli anni '90 e nei primi anni 2000 le connessioni a bassa latenza non erano comuni. Un modem dialup avrebbe una latenza unidirezionale tipica di 180 ms. Aspettare un attimo prima di inviare un altro aggiornamento, raddoppiando effettivamente quel tempo a 360 ms, è stato doloroso; anche gli utenti alle prime armi potrebbero sicuramente sentire la differenza. Quando le connessioni a banda larga hanno preso piede, hanno abbassato molto la latenza, ma ha continuato a persistere quando la larghezza di banda era scarsa (abbastanza spesso in alcune aree). Quindi persisteva la preferenza per la latenza più bassa possibile.

Le connessioni e le interconnessioni domestiche moderne hanno cambiato questo, al punto in cui la latenza regionale, anche durante le ore congestionate del giorno, è nel raggio di 15 ms o inferiore. Scegliere TCP anziché UDP sarebbe invisibile nella maggior parte dei casi, poiché la latenza è "abbastanza bassa". Tuttavia, esiste ancora la tendenza di assegnare priorità a UDP su TCP data la sua storia come protocollo a bassa latenza. Quindi, per ora (e probabilmente qualche tempo nel futuro) UDP sarà preferito per la comunicazione in tempo reale.


La latenza sarebbe abbastanza bassa, tranne che per impostazione predefinita, le scritture TCP vengono inviate solo quando i dati da scrivere attraversano una determinata soglia o si verifica un timeout (di solito 200-1000 ms). Se hai bisogno di TCP su un sistema a bassa latenza con un throughput ridotto, devi disabilitare questa funzione e assicurarti di non scrivere sempre singoli byte (ad es. Non stai più trattando il flusso TCP come flusso e fai finta di essere invece hai a che fare con singoli messaggi). Non devi aspettare l'ACK a meno che i tuoi buffer non siano pieni, il che è abbastanza improbabile che accada in un tipico gioco in tempo reale.
Luaan,

1
@Luaan Enter: il flag TCP PSH. Quando un'applicazione lo passa nello stack, il pacchetto viene inviato immediatamente senza attendere ulteriori dati. Molte applicazioni lo usano con successo (telnet e ssh per esempio).
Jeff Meden,

2

So che UDP è di solito raccomandato per i giochi multiplayer in tempo reale con un elevato utilizzo dei dati
UDP è ancora superiore in termini di velocità e latenza? Le recenti ottimizzazioni TCP potrebbero rendere le prestazioni TCP migliori di UDP?

I tuoi presupposti sono sbagliati. TCP e UDP differiscono principalmente nel modello che rappresentano (datagrammi inaffidabili rispetto a flussi virtuali affidabili in ordine).

Non differiscono per volume ("elevato utilizzo dei dati") o velocità effettiva. TCP invierà la stessa quantità di dati di UDP, saturando facilmente il cavo fisico.

In presenza di perdita di pacchetti, i due differiscono nella latenza, ma solo in quella condizione. Altrimenti, TCP ha una latenza altrettanto bassa di UDP (dare o prendere forse una dozzina di nanosecondi perché lo stack di rete ha un po 'più di logica da fare, ma è piuttosto trascurabile).
C'è una leggera differenza nella dimensione dell'intestazione, quindi tecnicamente, più byte devono passare attraverso il cavo su linee seriali, ma anche quello è piuttosto irrilevante. Importa davvero solo per i trasferimenti di massa, quindi una differenza dello 0,5% circa. La maggior parte delle persone con accesso a Internet DSL domestico indirizzano tutto il loro traffico su ATM, aumentando il sovraccarico del protocollo del 10% (5 byte di controllo per 48 byte di payload, più i frame parziali) e nessuno se ne accorge nemmeno.

Alcune persone costruiscono affidabilità su UDP. Se si desidera un certo livello di affidabilità, ma non è necessaria una consegna rigorosa in ordine, ciò può dare un piccolo vantaggio. Tuttavia, è ancora discutibile se l'approccio abbia molto senso e si paga un prezzo elevato per quel piccolo vantaggio.
Se hai clienti che si connettono da hotel WiFis o altri luoghi "strani", noterai che spesso il supporto complessivo per TCP è molto, molto meglio di UDP.

I giochi generalmente usano UDP non perché è superiore in uno dei modi sopra menzionati - non lo è - o perché è possibile ridurre il jitter di mezzo millesimo di secondo implementando l'affidabilità senza in ordine, ma perché i giochi (molto simili alla telefonia IP) spesso contengono molti dati molto volatili, come ad esempio gli aggiornamenti di posizione.
Questi dati volatili sono regolarmente e rapidamente obsoleti sia con il passare del tempo, sia con il prossimo datagramma che entra. Il che significa niente di più e niente di meno che in realtà non ti interessa troppo essere affidabile al 100% (o in ordine).

Supponendo che un pacchetto di rete venga rilasciato in un servizio che funziona a un ritmo costante con frequenti aggiornamenti in arrivo (gioco sparatutto, telefono, chat video), non ha molto senso avere il timeout di riconoscimento e inviare nuovamente il pacchetto, e nel frattempo congela tutto dall'altra parte mentre aspetta che arrivi il pacchetto risentito. È troppo inquietante e non va bene.

Invece, consideri semplicemente il pacchetto perso e vai avanti, prendendo i dati dal pacchetto successivo che lo attraversa e nel frattempo, al meglio delle tue possibilità, nascondi il fatto che un pacchetto è stato perso dall'utente. Interpolazione, resa dei conti morta, tu lo chiami.

Si noti che la perdita di pacchetti è una condizione normale. Mentre l'IP è generalmente "abbastanza affidabile", i pacchetti che occasionalmente vengono eliminati possono accadere e accadranno . Mentre i pacchetti persi sono normalmente piuttosto rari (<1% qui), non è qualcosa di straordinario o teorico, o un'indicazione che qualcosa è rotto. È perfettamente normale.
Ogni trasferimento di massa TCP includerà necessariamente pacchetti persi, ad esempio (è come funziona il controllo della congestione).


2

In un MPG ad alta larghezza di banda, non ti importa se hai perso un pacchetto che ti fornisce la posizione e la salute del mostro # 425, perché otterrai un altro aggiornamento in una frazione di secondo. Questo è un esempio in cui UDP rende stupido TCP per farti aspettare dati istantaneamente obsoleti.

In quello stesso gioco, vuoi che le patch vengano visualizzate esattamente come sono state progettate. TCP ha già le funzionalità "dimmi se non funziona", che facilitano i tentativi automatici e gli errori verificati. Puoi farlo in UDP, ma perché ricreare la tecnologia?

Ecco una semplice descrizione di ciò che sta succedendo.

UDP - Isola il pezzo di O'data.
Crea un pacchetto.
Incapsulare in IP.
Spedirlo.

TCP: isola un flusso di O'data.
Crea un pacchetto dalla parte anteriore del flusso.
Incapsulare in IP.
Attendere lo spazio nella finestra TCP.
Spedirlo.
Continuare a rispedire fino alla ricezione di una ricevuta o al timeout.
Rimani nella finestra TCP fino a quando non viene ricevuta una ricevuta o il timeout.

La spedizione significa solo che è arrivata attraverso la NIC locale, non di più.

Una ricezione ricevuta TCP garantisce sia la ricezione dei dati che libera spazio nella finestra per il pacchetto successivo.

Rinviare (leggermente) aumenta la probabilità di eventuale ricezione.

I pacchetti TCP vengono riassemblati dall'altra parte come un flusso di dati ordinato. I pacchetti UPD vengono ricevuti come pacchetto distinto. Il protocollo non mantiene l'ordine.

TCP è utile per inviare i dati richiesti e grandi quantità ordinate di dati. TCP fornisce la notifica di un errore persistente. TCP auto-gas attraverso tubi strozzati (rif: finestra). TCP ha delle strette di mano per rallentare l'inizializzazione. TCP richiede una "connessione" prima della trasmissione.

UDP mette semplicemente i dati sul filo e ti consente di procedere senza aspettare finestre e ritrasmissioni. UDP farà esplodere i dati a tutta velocità in un tubo strozzato, indipendentemente dalla quantità di dati persi.

Ho progettato e scritto un'utility UDP Multicast File Transport per uso commerciale. Ho lavorato su stack IP. Queste sono solo nozioni di base, sans minutia. Spiegare "socket, MTU e altri giocattoli divertenti" era un po 'oltre ciò che sarebbe utile per questa domanda.

Ps (non riesco ad aggiungere commenti per rispondere ai commenti) UDP è buono anche per i dati desiderabili ma non richiesti. Forward Error Correction ne è un esempio, molti pacchetti non necessari ma desiderabili.


3
Il tuo punto sui dati "obsoleti" è positivo. TCP è buono per i dati "meglio tardi che mai", ma UDP è buono per i dati che saranno utili se raggiungono rapidamente la destinazione, ma inutili se non lo fanno.
supercat,

1

Tutti i router ottimizzati TCP hanno migliorato le prestazioni di TCP rispetto a UDP?

Un'altra domanda è: "dati pesanti" significa che caricherai spesso scene?

In caso affermativo, potrebbe essere necessario inviare grandi quantità di dati (> 1k) in modo intensivo in cui TCP potrebbe essere molto più efficiente poiché, soprattutto sul lato server, le schede NIC forniranno vari offload con lo stesso numero di cicli. Un'applicazione di spazio utente può eseguire scritture di grandi dimensioni con TCP mentre in UDP un tentativo di inviare più di byte di dimensioni di intestazioni MTU provocherà la frammentazione IP e altri costi generali che compromettono le prestazioni


È un gioco "voxel", quindi sì, dovrà inviare molti dati di scena.
KaareZ,

@KaareZ Beh, probabilmente vorrai comunque inviarli come singoli messaggi indipendenti in quel caso, con i tuoi meccanismi di ritrasmissione. Minecraft è iniziato su TCP ed era praticamente ingiocabile su Internet; il passaggio a UDP è stata un'occasione felice per la maggior parte delle persone. L'idea principale è che quando si inviano 20 blocchi di dati voxel e il primo viene "perso", non dovrebbe impedire agli altri 19 blocchi di essere visualizzati non appena si ottengono i dati; quando scopri che manca il primo, lo ritrasmetti. Su TCP, tutti questi 19 sono bloccati per lo meno e ritrasmessi nel caso peggiore.
Luaan,

2
@Luaan Minecraft non è passato a UDP per il gameplay attuale. Anche le ultime versioni usano ancora TCP. Nessuna occasione felice ... :( L'unica parte di Minecraft che utilizza UDP è l'elenco dei server, per eseguire il ping dei singoli server e determinare se sono online.
camerondm9

1

Né UDP né TCP (o qualsiasi altra variante) sono di gran lunga superiori , nemmeno in termini di velocità / latenza. La scelta deve essere effettuata in base ai requisiti dell'applicazione. Per fare ciò, è necessario confrontare le funzionalità offerte da ciascun protocollo, rendendosi conto che un numero maggiore di funzionalità implica un sovraccarico. Pertanto, se l'obiettivo è ridurre al minimo la latenza o massimizzare la velocità, è necessario scegliere un protocollo con il minor numero possibile di funzionalità, pur mantenendo le funzionalità essenziali necessarie per soddisfare le proprie esigenze.

Un confronto di protocolli

In generale, UDP (User Datagram Protocol) offre il minor numero di funzionalità. È semplicistico in quanto si inviano dati senza alcun tipo di ricevuta / conferma.

D'altro canto, TCP (Transmission Control Protocol) offre la maggior parte delle funzionalità necessarie per una comunicazione affidabile e connessa. Una comunicazione TCP invia duplicati o più di pacchetti e li contrassegna con le informazioni di ordinamento. Al ricevimento a destinazione, un ACK (conferma) deve essere rispedito insieme alle informazioni su quali pacchetti sono stati persi in modo che il mittente originale possa rinviare quei pacchetti persi. Se ricordo bene, anche i pacchetti ACK potrebbero necessitare di riconoscimento per la corretta affidabilità.


Esempio: chiamata in conferenza di Skype

Per una chiamata in conferenza di Skype, non è importante garantire che tutti i dati audio e video vengano inviati / ricevuti in modo affidabile. Al giorno d'oggi, UDP fa un ottimo lavoro nel ridurre al minimo la perdita di pacchetti. La cosa importante da sapere è che non esiste assolutamente alcuna garanzia in UDP se la trasmissione abbia avuto successo. Per i dati audio / video in una chiamata in conferenza, UDP è la scelta giusta perché ci preoccupiamo di più di ottenere dati in tempo reale (ovvero i più recenti). Se alcuni pacchetti vengono persi qua e là, non interromperà la comunicazione in modo drammatico.

Tuttavia, durante una chiamata in conferenza, le persone possono inviare messaggi istantanei (IM) o inviare file. In questi casi, l'affidabilità è un requisito necessario per garantire che file e messaggi non vengano danneggiati o persi. Per i messaggi istantanei potrebbe non essere necessario lo stato connesso fornito da TCP. Un protocollo intermedio, come RUDP (Reliable UDP), può essere sufficiente. Tuttavia, per i file, potrebbe essere necessario avere lo stato connesso fornito da TCP.


Scelte di implementazione

Se si dispone di un'applicazione complessa o è necessario ottimizzare la comunicazione, è utile iniziare con una comunicazione UDP. Successivamente, puoi aggiungere tutte le funzionalità di cui hai bisogno in cima. Questo ti darà il massimo controllo sulla comunicazione di rete.

Se hai una semplice applicazione in cui non è richiesta l'ottimizzazione, prendi in considerazione la possibilità di sceglierne uno standard (UDP o TCP) per soddisfare le tue esigenze. Ciò ti consentirebbe di passare ad argomenti più importanti.


1

Ho notato molti commenti in cui le persone credono che i pacchetti TCP siano più grandi dei pacchetti UDP. Non fidarti di me, leggi la documentazione. Il protocollo è il seguente: alcuni byte per l'intestazione Ethernet (tipo di messaggio 2 byte, MAC a 48 bit, 6 byte) (per Wifi, l'intestazione può differire) 20 byte per IP 20 byte per TCP o UDP x byte per i dati x range da 0 a circa 1500 (vedi MTU) Infine, il checksum per assicurarsi che non si sia verificato alcun danneggiamento in quel pacchetto Ethernet.

TCP consente di inviare pacchetti "stream" più grandi di circa 64 KB. Questo blocco "grande" è effettivamente suddiviso in molti pacchetti Ethernet più piccoli.


Stai cercando di suggerire che le intestazioni UDP e TCP hanno le stesse dimensioni?
Cameron,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.