Per lo scambio di messaggi di protocollo generale, che può tollerare una perdita di pacchetti. Quanto è più efficiente UDP su TCP?
Per lo scambio di messaggi di protocollo generale, che può tollerare una perdita di pacchetti. Quanto è più efficiente UDP su TCP?
Risposte:
UDP è più veloce di TCP e la semplice ragione è perché il suo pacchetto di riconoscimento (ACK) inesistente che consente un flusso di pacchetti continuo, anziché TCP che riconosce un insieme di pacchetti, calcolato utilizzando la dimensione della finestra TCP e il tempo di andata e ritorno (RTT).
Per ulteriori informazioni, raccomando la spiegazione Skullbox semplice ma molto comprensibile (TCP vs. UDP)
La gente dice che la cosa principale che TCP ti dà è l'affidabilità. Ma questo non è proprio vero. La cosa più importante che ti dà TCP è il controllo della congestione: puoi eseguire 100 connessioni TCP su un collegamento DSL tutte andando alla massima velocità e tutte e 100 le connessioni saranno produttive, perché "percepiscono" tutta la larghezza di banda disponibile. Provalo con 100 diverse applicazioni UDP, spingendo tutti i pacchetti il più velocemente possibile e vedi come funzionano le cose per te.
Su larga scala, questo comportamento TCP è ciò che impedisce a Internet di bloccarsi nel "collasso della congestione".
Cose che tendono a spingere le applicazioni verso UDP:
Semantica della consegna di gruppo: è possibile eseguire consegne affidabili a un gruppo di persone in modo molto più efficiente rispetto al riconoscimento punto-punto di TCP.
Consegna fuori ordine: in molte applicazioni, purché si ottengano tutti i dati, non ti interessa l'ordine in cui arrivano; puoi ridurre la latenza a livello di app accettando un blocco fuori ordine.
Scortesia: in una festa LAN, potrebbe non interessarti se il tuo browser web funziona bene fintanto che stai inviando aggiornamenti alla rete il più velocemente possibile.
Ma anche se ti preoccupi delle 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 quanto già faccia TCP.
Ora sei ostile alla rete, il che può causare problemi negli ambienti condivisi.
Ancora più importante, i firewall ti bloccheranno.
È possibile superare potenzialmente alcuni problemi di prestazioni e latenza TCP "trunking" più connessioni TCP insieme; iSCSI lo fa per aggirare il controllo della congestione sulle reti locali, ma puoi anche farlo per creare un canale di messaggi "urgenti" a bassa latenza (il comportamento "URGENTE" di TCP è totalmente rotto).
listen
-> accept
-> lo stato del client è naturalmente indipendente dagli altri client). La gestione di più connessioni da un singolo client in particolare diventa nodosa con UDP. E un punto a favore di UDP è che gli stack UDP sono davvero facili da implementare, il che è un enorme vantaggio per i sistemi embedded (microcontrollori, FPGA, ecc., In particolare un'implementazione TCP per un FPGA è generalmente qualcosa che desideri acquistare da qualcun altro e non pensarci).
In alcune applicazioni TCP è più veloce (migliore throughput) di UDP.
Questo è il caso quando si eseguono molte piccole scritture relative alla dimensione MTU. Ad esempio, ho letto un esperimento in cui un flusso di pacchetti da 300 byte veniva inviato su Ethernet (MTU a 1500 byte) e TCP era il 50% più veloce di UDP .
Il motivo è che TCP proverà a bufferizzare i dati e riempirà un intero segmento di rete facendo un uso più efficiente della larghezza di banda disponibile.
UDP d'altra parte mette il pacchetto sul filo immediatamente congestionando così la rete con molti piccoli pacchetti.
Probabilmente non dovresti usare UDP a meno che tu non abbia un motivo molto specifico per farlo. Soprattutto perché puoi dare a 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 alle perdite
Intendi "con tolleranza alla perdita"?
Fondamentalmente, UDP non è "tollerante alla perdita". Puoi inviare 100 pacchetti a qualcuno, che potrebbe ottenere 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 ovvia
Per la maggior parte delle altre cose, un pacchetto mancante o "riorganizzato" è fondamentale. Dovresti scrivere del codice aggiuntivo per eseguire UDP per riprovare se le cose si sono perse e applicare l'ordine corretto. Ciò aggiungerebbe un po 'di sovraccarico in alcuni punti.
Per fortuna, alcune persone molto intelligenti l'hanno fatto e lo hanno chiamato TCP.
Pensala in questo modo: se un pacchetto scompare, preferiresti semplicemente ottenere il pacchetto successivo il più rapidamente possibile e continuare (usare UDP), oppure hai effettivamente bisogno di quei dati mancanti (usa TCP). Il sovraccarico non importerà a meno che tu non sia in uno scenario davvero marginale.
Quale protocollo funziona meglio (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 ha prestazioni migliori (scritture di piccole dimensioni). Ora, considera uno scenario in cui la rete è congestionata e ha traffico TCP e UDP. I mittenti nella rete che utilizzano TCP percepiranno la "congestione" e ridurranno le loro velocità di invio. Tuttavia, UDP non ha alcun meccanismo di prevenzione della congestione o controllo della congestione e i mittenti che utilizzano UDP continuerebbero a immettere dati alla stessa velocità. A poco a poco, i mittenti TCP ridurrebbero al minimo le loro velocità di invio e se i mittenti UDP hanno abbastanza dati per essere inviati sulla rete, aumenterebbero la maggior parte della larghezza di banda disponibile. Quindi, in tal caso, I mittenti UDP avranno un throughput maggiore, poiché ottengono la più grande torta 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 conosco, che utilizza le applicazioni TCP in grado di migliorare la velocità è l'apertura di più connessioni TCP. In questo modo, anche se la velocità effettiva di ciascuna connessione TCP potrebbe essere limitata, la somma totale della velocità effettiva di tutte le connessioni TCP potrebbe essere maggiore della velocità effettiva di un'applicazione che utilizza UDP.
Quando si parla di "ciò che è più veloce" - ci sono almeno due aspetti molto diversi: rendimento e latenza.
Se si parla di throughput - il controllo del flusso di TCP (come menzionato in altre risposte), è estremamente importante e fare qualcosa di paragonabile a UDP, sebbene certamente possibile, sarebbe un grosso mal di testa (tm). Di conseguenza, l'utilizzo di UDP quando è necessario il throughput , raramente si qualifica come una buona idea (a meno che non si desideri ottenere un vantaggio sleale su TCP).
Tuttavia, se si parla di latenze , il tutto è completamente diverso. Mentre in assenza di perdita di pacchetti TCP e UDP si comportano in modo estremamente simile (qualsiasi differenza, se presente, essendo marginale) - dopo la perdita del pacchetto, l'intero modello cambia drasticamente.
Dopo qualsiasi perdita di pacchetti, TCP attenderà la ritrasmissione per almeno 200 ms (1 secondo al paragrafo 2.4 di RFC6298, ma le implementazioni moderne e pratiche tendono a ridurlo a 200 ms). Inoltre, con TCP, anche quei pacchetti che hanno raggiunto l'host di destinazione - non saranno consegnati alla tua app fino a quando non viene ricevuto il pacchetto mancante (ovvero, l'intera comunicazione è ritardata di ~ 200ms) - A proposito, questo effetto, noto come Head-of -Line Blocking, è inerente a tutti i flussi ordinati affidabili, siano essi TCP o affidabili + UDP ordinati. A peggiorare le cose: se si perde anche il pacchetto ritrasmesso, si parlerà di un ritardo di ~ 600 ms (a causa del cosiddetto backoff esponenziale, il primo ritrasmesso è 200 ms e il secondo è 200 * 2 = 400 ms). Se il nostro canale ha una perdita di pacchetti dell'1% (che non è male per gli standard di oggi), e abbiamo un gioco con 20 aggiornamenti al secondo - tali ritardi di 600ms si verificano in media ogni 8 minuti. E poiché 600 ms sono più che sufficienti per farti uccidere in un gioco frenetico - beh, è piuttosto male per il gameplay. Questi effetti sono esattamente il motivo per cui i Gamedev preferiscono spesso UDP su TCP.
Tuttavia, quando si utilizza UDP per ridurre le latenze, è importante rendersi conto che il semplice "utilizzo di UDP" non è sufficiente per ottenere un sostanziale miglioramento della latenza, è tutto su COME si utilizza UDP. In particolare, mentre le librerie RUDP di solito evitano quel "backoff esponenziale" e usano tempi di ritrasmissione più brevi - se sono usate come stream "affidabili ordinati", devono comunque soffrire di Head-of-Line Blocking (quindi nel caso di un doppio perdita di pacchetti, invece di quei 600ms otterremo circa 1,5 * 2 * RTT - o per un RTT abbastanza buono da 80ms, è un ritardo di ~ 250ms, che è un miglioramento, ma è ancora possibile fare di meglio). D'altra parte, se si utilizzano le tecniche discusse in http://gafferongames.com/networked-physics/snapshot-compression/ e / o http: // ithare. , È possibile eliminare completamente il blocco Head-of-Line (quindi per una perdita a doppio pacchetto per un gioco con 20 aggiornamenti / secondo, il ritardo sarà di 100 ms indipendentemente da RTT).
E come nota a margine - se ti capita di avere accesso solo a TCP ma senza UDP (come nel browser o se il tuo client è dietro 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 (!)).
Ogni connessione TCP richiede una stretta di mano iniziale prima che i dati vengano trasmessi. Inoltre, l'intestazione TCP contiene molti overhead destinati a diversi segnali e rilevamento della consegna dei messaggi. Per uno scambio di messaggi, probabilmente UDP sarà sufficiente se è accettabile una piccola possibilità di errore. Se la ricevuta deve essere verificata, TCP è l'opzione migliore.
@Andrew , mi permetto di dissentire. UDP è la scelta in alcuni tipi di applicazione a causa dei requisiti di prestazione. Un esempio classico è la videoconferenza. Questo tipo di applicazione non risponde bene al controllo TCP.
Un altro aspetto da prendere in considerazione è se hai bisogno del multicast. In tal caso, utilizzare UDP.
Voglio solo chiarire le cose. TCP / UDP sono due macchine che sono guidate su strada. supponiamo che i segnali stradali e gli ostacoli siano errori TCP si prende cura dei segnali stradali, rispetta tutto ciò che li circonda. Guida lenta perché potrebbe succedere qualcosa all'auto. Mentre UDP si allontana, la massima velocità non ha rispetto per i segnali stradali. Niente, un guidatore pazzo. UDP non ha il recupero degli errori, se c'è un ostacolo, si scontrerà con esso e continuerà. Mentre TCP si assicura che tutti i pacchetti vengano inviati e ricevuti perfettamente, nessun errore, quindi l'auto supera gli ostacoli senza scontrarsi. Spero che questo sia un buon esempio per farti capire, perché UDP è preferito nei giochi. Il gioco ha bisogno di velocità. TCP è prefferito nei download oppure i file scaricati potrebbero essere danneggiati.
UDP è leggermente più veloce nella mia esperienza, ma non di molto. La scelta non dovrebbe essere fatta in base alle prestazioni ma al contenuto del messaggio e alle tecniche di compressione.
Se si tratta di un protocollo con scambio di messaggi , suggerirei che la minima prestazione ottenuta con TCP è più che valsa la pena. Ti viene data una connessione tra due punti finali che ti darà tutto ciò di cui hai bisogno. Non provare a produrre il tuo affidabile protocollo bidirezionale su UDP a meno che tu non sia davvero molto sicuro di ciò che stai intraprendendo.
Tieni presente che TCP di solito mantiene più messaggi in transito. Se vuoi implementarlo in UDP, avrai un sacco di lavoro se vuoi farlo in modo affidabile. La tua soluzione sarà meno affidabile, meno veloce o una quantità incredibile di lavoro. Esistono applicazioni valide di UDP, ma se stai ponendo questa domanda probabilmente non lo è.
C'è stato del lavoro fatto per consentire al programmatore di avere i vantaggi di entrambi i mondi.
SCTP
È un protocollo di livello di trasporto indipendente, ma può essere utilizzato come libreria che fornisce un livello aggiuntivo su UDP. L'unità base di comunicazione è un messaggio (associato a uno o più pacchetti UDP). È integrato il controllo della congestione. Il protocollo ha manopole e twiddle da attivare
se uno di questi è necessario per la tua specifica applicazione
Un problema con questo è che la creazione della connessione è un processo complicato (e quindi lento)
Altre cose simili
Un'altra cosa sperimentale proprietaria simile
Ciò cerca anche di migliorare la stretta di mano tripla di TCP e di modificare il controllo della congestione per gestire meglio le linee veloci.
Non ha senso parlare di TCP o UDP senza prendere in considerazione le condizioni di rete. Se la rete tra i due punti ha una qualità molto elevata, UDP è assolutamente più veloce di TCP, ma in alcuni altri casi 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 stai comunicando tramite prese sul tuo computer locale o con l'altra estremità del mondo.
Tre cose che voglio aggiungere alla discussione: