UDP vs TCP, quanto è più veloce?

Per lo scambio di messaggi di protocollo generale, che può tollerare una perdita di pacchetti. Quanto è più efficiente UDP su TCP?

UDP è più veloce di TCP, e la ragione semplice è perché il suo inesistente pacchetto di riconoscimento (ACK) che consente un stream di pacchetti continuo, anziché TCP che riconosce un insieme di pacchetti, calcolato usando la dimensione della finestra TCP e il tempo di andata e ritorno (RTT) ).

Per maggiori informazioni raccomando la spiegazione semplice, ma comprensibile di Skullbox (TCP vs. UDP)

La gente dice che la cosa principale che ti dà TCP è l’affidabilità. Ma non è proprio vero. La cosa più importante che TCP ti dà è il controllo della congestione: puoi eseguire 100 connessioni TCP su un collegamento DSL andando alla massima velocità e tutte le 100 connessioni saranno produttive, perché tutti “percepiscono” la larghezza di banda disponibile. Provalo con 100 diverse applicazioni UDP, spingendo tutti i pacchetti il ​​più velocemente ansible e vedi come funzionano le cose per te.

Su scala più ampia, questo comportamento TCP è ciò che impedisce a Internet di bloccarsi in “congestion collapse”.

Cose che tendono a spingere le applicazioni verso UDP:

  • Semantica di consegna di gruppo: è ansible eseguire consegne affidabili a un gruppo di persone in modo molto più efficiente rispetto alla conferma da punto a punto del TCP.

  • Consegna fuori ordine: in molte applicazioni, finché si ottengono tutti i dati, non si cura di quale ordine arrivi; puoi ridurre la latenza a livello di app accettando un blocco out-of-order.

  • Scortesia: su una festa in LAN, non ti importa se il tuo browser funziona bene fino a quando stai blittando gli aggiornamenti alla rete il più velocemente ansible.

Ma anche se ti interessano le prestazioni, probabilmente non vuoi andare con UDP:

  • Ora sei pronto per l’affidabilità e molte delle cose che potresti fare per implementare l’affidabilità possono finire per essere più lente di quelle già utilizzate da TCP.

  • Ora sei in una rete ostile, che può causare problemi negli ambienti condivisi.

  • Ancora più importante, i firewall ti bloccheranno.

È ansible superare alcuni problemi di prestazioni e latenza TCP “trunking” di più connessioni TCP; iSCSI fa questo per aggirare il controllo della congestione sulle reti locali, ma è anche ansible farlo per creare un canale di messaggi “urgenti” a bassa latenza (il comportamento “URGENTE” di TCP è totalmente interrotto).

In alcune applicazioni, TCP è più veloce (migliore velocità effettiva) di UDP.

Questo è il caso quando si eseguono molte piccole scritture relative alla dimensione MTU. Ad esempio, ho letto un esperimento in cui un stream di pacchetti da 300 byte veniva inviato su Ethernet (MTU da 1500 byte) e TCP era il 50% più veloce di UDP .

La ragione è che il TCP proverà a tamponare i dati e riempire un intero segmento di rete, rendendo così più efficiente l’uso della larghezza di banda disponibile.

UDP, d’altra parte, mette immediatamente il pacchetto sul cavo e quindi congestiona la rete con molti piccoli pacchetti.

Probabilmente non dovresti usare UDP a meno che tu non abbia una ragione molto specifica per farlo. Tanto più che puoi dare al TCP lo stesso tipo di latenza di UDP disabilitando l’ algoritmo Nagle (ad esempio se stai trasmettendo dati di sensori in tempo reale e non sei preoccupato di congestionare la rete con molti piccoli pacchetti).

con tolleranza tollerante

Intendi “con tolleranza alla perdita”?

Fondamentalmente, UDP non è “tollerante alle perdite”. Puoi inviare 100 pacchetti a qualcuno e potrebbero ricevere solo 95 di questi pacchetti e alcuni potrebbero essere nell’ordine sbagliato.

Per cose come lo streaming video e il gioco multiplayer, dove è meglio perdere un pacchetto piuttosto che ritardare tutti gli altri pacchetti dietro di esso, questa è la scelta più ovvia

Per la maggior parte delle altre cose, un pacchetto mancante o “riarrangiato” è fondamentale. Dovresti scrivere del codice extra da eseguire su UDP per riprovare se le cose si sono perse e far rispettare l’ordine corretto. Ciò aggiungerebbe un po ‘di sovraccarico in determinati luoghi.

Per fortuna, alcune persone molto intelligenti lo hanno fatto e lo hanno chiamato TCP.

Pensala in questo modo: se un pacchetto scompare, preferiresti semplicemente ottenere il pacchetto successivo il più rapidamente ansible e continuare (usare UDP), o hai effettivamente bisogno di quei dati mancanti (usa TCP). L’overhead non ha importanza a meno che tu non sia in uno scenario davvero limite.

Quale protocollo migliori (in termini di throughput) – UDP o TCP – dipende in realtà dalle caratteristiche della rete e dal traffico di rete. Robert S. Barnes, ad esempio, indica uno scenario in cui TCP si comporta meglio (scritture di piccole dimensioni). Ora, considera uno scenario in cui la rete è congestionata e ha sia il traffico TCP che UDP. I mittenti nella rete che utilizzano TCP, percepiranno la “congestione” e ridurranno i loro tassi di invio. Tuttavia, UDP non ha meccanismi di prevenzione della congestione o di controllo della congestione, ei mittenti che usano UDP continuerebbero a pompare dati alla stessa velocità. A poco a poco, i mittenti TCP avrebbero ridotto al minimo le loro tariffe di invio e se i mittenti UDP avessero dati sufficienti per essere inviati attraverso la rete, avrebbero sfruttato la maggior parte della larghezza di banda disponibile. Quindi, in tal caso, i mittenti UDP avranno un throughput maggiore, in quanto ottengono la torta più ampia della larghezza di banda della rete. In realtà, questo è un argomento di ricerca attivo – Come migliorare il throughput TCP in presenza di traffico UDP. Un modo, che io sappia, usando quali applicazioni TCP possono migliorare il throughput è aprendo più connessioni TCP. In questo modo, anche se il throughput di ciascuna connessione TCP potrebbe essere limitato, la sum totale della velocità effettiva di tutte le connessioni TCP potrebbe essere maggiore della velocità effettiva per un’applicazione che utilizza UDP.

Ogni connessione TCP richiede un handshake iniziale prima che i dati vengano trasmessi. Inoltre, l’intestazione TCP contiene molti overhead destinati a segnali diversi e al rilevamento della consegna dei messaggi. Per uno scambio di messaggi, UDP sarà probabilmente sufficiente se una piccola possibilità di fallimento è accettabile. Se la ricevuta deve essere verificata, TCP è l’opzione migliore.

@ Andrew , mi permetto di dissentire. UDP è la scelta in alcuni tipi di applicazioni a causa dei requisiti prestazionali. Un classico esempio è la videoconferenza. Questo tipo di applicazione non risponde bene al controllo TCP.

Un altro aspetto da tenere in considerazione è se hai bisogno di multicast. Se è così, usa UDP.

Quando si parla di “ciò che è più veloce” – ci sono almeno due aspetti molto diversi: velocità effettiva e latenza.

Se si parla di throughput – il controllo del stream di TCP (come menzionato in altre risposte), è estremamente importante e fare qualcosa di paragonabile a UDP, anche se certamente ansible, sarebbe un Big Headache ™. Di conseguenza, utilizzare UDP quando è necessario un throughput , raramente si qualifica come una buona idea (a meno che non si desideri ottenere un vantaggio ingiusto sul TCP).

Tuttavia, se si parla di latenze – l’intera faccenda è completamente diversa. Mentre in assenza di perdita di pacchetti TCP e UDP si comportano in modo estremamente simile (eventuali differenze, se presenti, sono marginali) – dopo la perdita del pacchetto, l’intero modello cambia drasticamente.

Dopo ogni perdita di pacchetti, TCP attenderà la ritrasmissione per almeno 200 ms (1 sec per paragrafo 2.4 di RFC6298, ma le implementazioni moderne pratiche tendono a ridurlo a 200 ms). Inoltre, con TCP, anche i pacchetti che hanno raggiunto l’host di destinazione non verranno consegnati alla tua app fino a quando il pacchetto mancante non viene ricevuto (cioè l’intera comunicazione viene ritardata di ~ 200ms) – BTW, questo effetto, noto come Head-of -Line Blocking, è inerente a tutti i flussi ordinati affidabili, sia TCP che affidabile + ordinato UDP. Per rendere le cose ancora peggiori – se anche il pacchetto ritrasmesso viene perso, allora parleremo di un ritardo di ~ 600ms (a causa del cosiddetto backoff esponenziale, 1 ° ritrasmissione è 200ms, e il secondo è 200 * 2 = 400ms). Se il nostro canale ha una perdita di pacchetti dell’1% (che non è male secondo gli standard odierni), e abbiamo un gioco con 20 aggiornamenti al secondo – tali ritardi di 600ms si verificano in media ogni 8 minuti. E come 600ms è più che sufficiente per farti uccidere in un gioco frenetico – beh, è ​​piuttosto brutto per il gameplay. Questi effetti sono esattamente il motivo per cui i gamedev spesso preferiscono UDP su TCP.

Tuttavia, quando si utilizza UDP per ridurre le latenze, è importante rendersi conto che semplicemente “usare UDP” non è sufficiente per ottenere un miglioramento sostanziale della latenza, ma è tutto su COME stai usando UDP. In particolare, mentre le librerie RUDP di solito evitano quel “backoff esponenziale” e usano tempi di ritrasmissione più brevi – se vengono utilizzati come stream “affidabili ordinati”, devono ancora soffrire di blocchi di Head of Line (quindi in caso di un doppio perdita di pacchetti, invece di 600ms otterremo circa 1.5 * 2 * RTT – o per un RTT 80ms piuttosto buono, è un ritardo di ~ 250ms, che è un miglioramento, ma è ancora ansible fare di meglio). D’altra parte, se si utilizzano tecniche discusse in http://gafferongames.com/networked-physics/snapshot-compression/ e / o http://ithare.com/udp-from-mog-perspective/#low-latency- compressione , è ansible eliminare completamente il blocco Head of Line (quindi per una perdita di pacchetti doppio per un gioco con 20 aggiornamenti al secondo, il ritardo sarà 100ms indipendentemente dalla RTT).

E come nota a margine – se ti capita di avere accesso solo al TCP ma nessun UDP (come nel browser, o se il tuo client è dietro a uno dei 6-9% dei brutti firewall che bloccano UDP) – sembra che ci sia un modo per implementare UDP-over-TCP senza incorrere in troppe latenze, vedere qui: http://ithare.com/almost-zero-additional-latency-udp-over-tcp/ (assicurarsi di leggere anche i commenti (!)).

UDP è leggermente più veloce nella mia esperienza, ma non di molto. La scelta non dovrebbe essere fatta sulle prestazioni ma sul contenuto del messaggio e sulle tecniche di compressione.

Se si tratta di un protocollo con scambio di messaggi, suggerirei che il leggerissimo colpo di prestazioni che si ottiene con TCP è più che utile. Ti viene data una connessione tra due punti finali che ti daranno tutto ciò di cui hai bisogno. Non provare a fabbricare il tuo protocollo affidabile a due vie su UDP, a meno che tu non sia realmente, molto fiducioso in quello che stai facendo.

Se hai bisogno di far saltare rapidamente un messaggio attraverso la rete tra due IP che non hanno ancora parlato, allora un UDP arriverà almeno 3 volte più velocemente, di solito 5 volte più veloce.

Tieni presente che TCP di solito mantiene più messaggi sul filo. Se vuoi implementarlo in UDP avrai un bel po ‘di lavoro se vuoi farlo in modo affidabile. La tua soluzione sarà meno affidabile, meno veloce o un’incredibile quantità di lavoro. Ci sono valide applicazioni di UDP, ma se stai facendo questa domanda probabilmente la tua non lo è.

C’è stato un lavoro fatto per permettere al programmatore di avere i benefici di entrambi i mondi.

SCTP

È un protololo a livello di trasporto indipendente, ma può essere usato come una libreria che fornisce uno strato aggiuntivo su UDP. L’unità di base della comunicazione è un messaggio (mappato a uno o più pacchetti UDP). C’è un controllo della congestione integrato. Il protocollo ha manopole e twiddles per accendere

  • nell’ordine di consegna dei messaggi
  • ritrasmissione automatica di messaggi persi, con parametri definiti dall’utente

se questo è necessario per la tua particolare applicazione.

Un problema con questo è che la creazione della connessione è un processo complicato (e quindi lento)

Altre cose simili

Un’altra cosa sperimentale di proprietà simile

Questo tenta anche di migliorare la tripla modalità di handshake del TCP e di modificare il controllo della congestione per gestire meglio le linee veloci.

Farò solo le cose chiare. TCP / UDP sono due macchine che vengono guidate su strada. supponiamo che i segnali stradali e gli ostacoli siano Errori TCP si prende cura dei segnali stradali, rispetta tutto intorno. Guida lenta perché qualcosa potrebbe accadere alla macchina. Mentre l’ UDP è appena partito, a tutta velocità, nessun rispetto per i segnali stradali. Niente, un autista pazzo. UDP non ha il recupero degli errori, se c’è un ostacolo, si scontrerà e continuerà. Mentre TCP si assicura che tutti i pacchetti siano inviati e ricevuti perfettamente, nessun errore, quindi, la macchina passa solo gli ostacoli senza scontrarsi. Spero che questo sia un buon esempio per capire, perché UDP è preferito nei giochi. Il gioco ha bisogno di velocità. TCP è preimpostato nei download, o i file scaricati possono essere corrotti.

Non ha senso parlare di TCP o UDP senza tener conto delle condizioni della rete. Se la rete tra i due punti ha una qualità molto elevata, UDP è assolutamente più veloce del TCP, ma in qualche altro caso come la rete GPRS, TCP potrebbe essere più veloce e più affidabile di UDP.

L’impostazione della rete è fondamentale per qualsiasi misurazione. Fa una grande differenza, se comunichi tramite prese sulla tua macchina locale o con l’altra estremità del mondo.

Tre cose che voglio aggiungere alla discussione:

  1. Puoi trovare qui un ottimo articolo su TCP vs UDP nel contesto dello sviluppo del gioco.
  2. Inoltre, iperf ( jperf migliora iperf con una GUI) è uno strumento molto carino per rispondere alla tua domanda tu stesso misurando.
  3. Ho implementato un benchmark in Python (vedi questa domanda SO ). In media di 10 ^ 6 iterazioni la differenza per l’invio di 8 byte è di circa 1-2 microsecondi per UDP.