Domanda

Se hai una situazione in cui una connessione TCP è potenzialmente troppo lenta e una 'connessione' UDP è potenzialmente troppo inaffidabile, cosa usi? Esistono vari protocolli UDP affidabili standard, quali esperienze hai con loro?

Si prega di discutere di un protocollo per risposta e se qualcun altro ha già menzionato quello che si utilizza, si consiglia di votarli e di utilizzare un commento per elaborare, se necessario.

Sono interessato alle varie opzioni qui, di cui TCP è a un'estremità della scala e UDP è all'altra. Sono disponibili varie opzioni UDP affidabili e ognuna porta alcuni elementi di TCP su UDP.

So che spesso TCP è la scelta corretta, ma avere un elenco delle alternative è spesso utile per aiutare a giungere a tale conclusione. Cose come Enet, RUDP, ecc. Che sono costruite su UDP hanno vari pro e contro, li hai usati, quali sono le tue esperienze?

A scanso di equivoci, non ci sono più informazioni, questa è una domanda ipotetica e quella che speravo potesse suscitare un elenco di risposte che descrivesse in dettaglio le varie opzioni e alternative disponibili per qualcuno che ha bisogno di prendere una decisione.

È stato utile?

Soluzione

È difficile rispondere a questa domanda senza alcune informazioni aggiuntive sul dominio del problema. Ad esempio, quale volume di dati stai usando? Quante volte? Qual è la natura dei dati? (es. è univoco, dati una tantum? O è un flusso di dati di esempio? ecc.) Per quale piattaforma stai sviluppando? (es. desktop / server / incorporato) Per determinare cosa intendi con "troppo lento", quale mezzo di rete stai utilizzando?

Ma, in termini (molto!) generali, penso che dovrai impegnarti molto per battere tcp per la velocità, a meno che tu non possa fare alcune assunzioni difficili sui dati che stai cercando di inviare.

Ad esempio, se i dati che stai tentando di inviare sono tali da poter tollerare la perdita di un singolo pacchetto (es. dati regolarmente campionati in cui la frequenza di campionamento è molte volte superiore alla larghezza di banda del segnale) probabilmente puoi sacrificare un po 'di affidabilità della trasmissione assicurandoti di poter rilevare il danneggiamento dei dati (ad es. attraverso l'uso di un buon crc)

Ma se non puoi tollerare la perdita di un singolo pacchetto, allora dovrai iniziare a introdurre i tipi di tecniche per l'affidabilità che tcp ha già. E, senza impegnarti in una quantità ragionevole di lavoro, potresti scoprire che stai iniziando a costruire quegli elementi in una soluzione spazio utente con tutti i problemi di velocità intrinseci da seguire.

Altri suggerimenti

Che dire di SCTP . È un protocollo standard dell'IETF (RFC 4960)

Ha capacità di chunking che potrebbero aiutare per la velocità.

Aggiornamento: un confronto tra TCP e SCTP mostra che le prestazioni sono comparabili a meno che due interfacce non possano essere utilizzato.

Aggiornamento: a bell'articolo introduttivo .

ENET - http://enet.bespin.org/

Ho lavorato con ENET come protocollo UDP affidabile e ho scritto una versione compatibile con socket asincroni per un mio cliente che lo sta utilizzando nei loro server. Funziona abbastanza bene ma non mi piace l'overhead che il ping peer to peer aggiunge a connessioni altrimenti inattive; quando hai un sacco di connessioni, esegui il ping tutti regolarmente è molto impegnativo.

ENET ti dà la possibilità di inviare più "canali" di dati e che i dati inviati siano inaffidabili, affidabili o in sequenza. Include anche il summenzionato ping peer to peer che funge da mantenitore in vita.

Abbiamo alcuni clienti del settore della difesa che utilizzano UDT (trasferimento dati basato su UDP) (vedi http: //udt.sourceforge .net / ) e ne sono molto contento. Vedo che ha anche una licenza BSD amichevole.

RUDP - Protocollo datagramma utente affidabile

Questo fornisce:

  • Riconoscimento dei pacchetti ricevuti
  • Controllo delle finestre e della congestione
  • Ritrasmissione di pacchetti persi
  • Overbuffering (più veloce dello streaming in tempo reale)

Sembra leggermente più configurabile per quanto riguarda mantenere attivi allora ENet ma non ti dà tante opzioni (cioè tutti i dati sono affidabili e sequenziati non solo i bit che decidi dovrebbero essere). Sembra abbastanza semplice da implementare.

Come altri hanno sottolineato, la tua domanda è molto generale e se qualcosa è "più veloce" di TCP dipende molto dal tipo di applicazione.

TCP è generalmente più veloce che mai per uno streaming affidabile di dati da un host a un altro. Tuttavia, se la tua applicazione fa molti piccoli scoppi di traffico e attende risposte, UDP potrebbe essere più appropriato per ridurre al minimo la latenza.

C'è una via di mezzo facile. L'algoritmo di Nagle è la parte di TCP che aiuta a garantire che il mittente non travolga il destinatario di un ampio flusso di dati, con conseguente congestione e perdita di pacchetti.

Se hai bisogno della consegna affidabile e in ordine di TCP e anche della risposta rapida di UDP, e non devi preoccuparti della congestione dall'invio di grandi flussi di dati, puoi disabilitare l'algoritmo di Nagle:

int opt = -1;
if (setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt)))
  printf("Error disabling Nagle's algorithm.\n");

Chiunque decida che l'elenco sopra non è sufficiente e che desidera sviluppare il proprio UDP PROPRIO dovrebbe assolutamente dare un'occhiata alle specifiche QUIC di Google in quanto copre molti casi angolari complicati e potenziali attacchi di negazione del servizio. Non ho ancora giocato con un'implementazione di questo, e potresti non volere o aver bisogno di tutto ciò che fornisce, ma vale la pena leggere il documento prima di intraprendere un nuovo "affidabile". Progettazione UDP.

Un buon punto di partenza per QUIC è qui , al Chromium Blog.

L'attuale documento di progettazione QUIC può essere trovato qui .

  

Se hai una situazione in cui una connessione TCP è potenzialmente troppo lenta e una 'connessione' UDP è potenzialmente troppo inaffidabile, cosa usi? Esistono vari protocolli UDP affidabili standard, quali esperienze hai con loro?

La parola chiave nella frase è 'potenzialmente'. Penso che tu debba davvero dimostrare a te stesso che TCP è, in effetti, troppo lento per le tue esigenze se hai bisogno di affidabilità nel tuo protocollo.

Se vuoi ottenere l'affidabilità da UDP, allora stai per implementare nuovamente alcune delle funzionalità di TCP su UDP, il che probabilmente renderà le cose più lente rispetto al semplice utilizzo di TCP in primo luogo.

Protocollo DCCP, standardizzato in RFC 4340 , " Datagram Congestion Control Protocol " potrebbe essere quello che stai cercando.

Sembra implementato in Linux .

Può essere RFC 5405 , " Linee guida di utilizzo UDP Unicast per progettisti di applicazioni " sarà utile per te.

Hai considerato di comprimere i tuoi dati?

Come indicato sopra, mancano informazioni sull'esatta natura del problema, ma la compressione dei dati per trasportarli potrebbe essere d'aiuto.

RUDP . Molti server socket per giochi implementano qualcosa di simile.

Il modo migliore per ottenere l'affidabilità usando UDP è costruire l'affidabilità nel programma applicativo stesso (ad esempio, aggiungendo meccanismi di riconoscimento e ritrasmissione)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top