2009-10-03 6 views
8

Abbiamo un sistema (integrato in C) che esegue la comunicazione su UDP. Recentemente abbiamo trovato la necessità di garantire la consegna dei pacchetti. La mia domanda è: quali sarebbero le aggiunte minime a un sistema basato su UDP per garantire la consegna utilizzando i pacchetti ack? Inoltre, idealmente senza dover manipolare le intestazioni dei pacchetti. Abbiamo il controllo del livello di applicazione sui pacchetti, compresi i numeri di sequenza e le bandiere ack/nack. Mi chiedo se questa è una causa persa e qualsiasi cosa tentiamo di fare sarà fondamentalmente una versione difettosa e rotta del TCP. Fondamentalmente, c'è un miglioramento minimalista che possiamo fare per ottenere una consegna garantita (non abbiamo bisogno di molte funzionalità di TCP come il controllo della congestione, ecc.). Grazie!implementando ack su UDP?

+1

Sei sicuro che ne valga la pena? Semplicemente usando una tecnologia provata rispetto a un sistema homebrew. Il vantaggio prestazionale è evidente o stai solo ottimizzando prematuramente? –

+0

Il sistema è in tempo reale e già conforme alle specifiche che richiedono UDP. –

risposta

0

Difficile problema. Direi che non sarai in grado di raggiungere l'affidabilità del TCP. Tuttavia, capisco che a volte, è necessario disporre di UDP affidabile.

Gamedev forum

RUDP (un po 'più hardcore)

Old Thread about reliable UDP

5

Date un'occhiata a Capitolo 8 e il Capitolo 20 di Steven UNIX Network Programming, volume 1. Egli copre un numero di approcci diversi. La sezione 20.5 "Aggiungere affidabilità ad un'applicazione UDP" è probabilmente la più interessante per te.

+0

+1 per un ottimo riferimento. Quando prima facevo qualcosa di simile per un incarico di programmazione, quella sezione era grandiosa. – mrduclaw

4

Ho una domanda in esecuzione here che sta raccogliendo le risposte a "Cosa usare quando è necessario UDP affidabile". Le risposte sono forse molto più di quanto tu voglia o hai bisogno ma potresti essere in grado di dare un'occhiata ad alcuni dei protocolli che sono stati costruiti su UDP e prendere solo la parte ACK di cui hai bisogno.

Dal mio lavoro con il protocollo ENet (un protocollo UDP affidabile), mi aspetto che sia necessario un numero di sequenza in ogni datagramma UDP, un modo di inviare un ACK per i datagrammi che hai ricevuto, un modo per tenerlo dei datagrammi che hai inviato fino a quando non ottieni un ACK per loro o scadono e un modo di temporizzare il reinvio dei datagrammi per i quali non hai ancora ricevuto un ACK ... Aggiungerei anche un timeout complessivo per quando decidi che non invierete mai un particolare datagramma e, suppongo, una richiamata al livello dell'applicazione per informarlo di questo errore di consegna ...

8

TCP intreccia 3 servizi che potrebbero essere rilevanti (okay TCP fa un molto di più, ma ne parlerò solo 3)

  1. in ordine di consegna
  2. consegna affidabile
  3. Controllo flusso

Hai appena detto che non è necessario il controllo di flusso, quindi non sarà nemmeno rispondere che (come si dovrebbe pubblicizzare una dimensione della finestra, ecc bene, tranne che probabilmente avrai bisogno di una finestra. ci arriverò.)

Hai detto che hai bisogno di una consegna affidabile. Non è troppo difficile - usi ACK per mostrare che il mittente ha ricevuto un pacchetto. la consegna affidabile di base assomiglia:

  1. mittente invia il pacchetto
  2. ricevitore riceve il pacchetto, e quindi invia un ACK
  3. Se il mittente non riceve un ACK (per mezzo di un timer), egli invia nuovamente il pacchetto.

Questi tre passaggi non affrontare questi problemi:

  1. Che cosa succede se l'ACK si perde?
  2. Cosa succede se i pacchetti arrivano fuori servizio?

Quindi, per la tua applicazione, hai detto che ti serviva solo una consegna affidabile, ma non hai detto nulla in merito alla necessità di ordinarli. Ciò influenzerà il modo in cui si implementa il protocollo.

(esempio in cui in-ordine non importa:.. Si sta copiando i record dei dipendenti da un computer ad un altro, non importa se il record di Alice viene ricevuto prima di Bob, a patto che sia arrivarci)

Quindi, presumendo che tu abbia solo bisogno di affidabilità (poiché è quello che hai detto nel tuo post), potresti ottenere questo in diversi modi.

Il mittente può tenere traccia dei pacchetti non riconosciuti. Quindi, se invia 3, 4, 5 e 6 e non ottiene un ACK per 3 e 4, il mittente sa che è necessario ritrasmetterlo. (Sebbene il mittente non sappia se i pacchetti 3 e 4 erano molti, o se i loro ACK sono andati persi.)

Ma allora il tuo mittente potrebbe fare ACK cumulativi - quindi nell'esempio precedente , sarebbe ack # 6 solo se avesse ricevuto 3, 4 e 5. Ciò significa che il ricevitore avrebbe rilasciare il pacchetto 6 se non avesse ricevuto prima il pacchetto. Se la tua rete è molto affidabile, questa potrebbe non essere una cattiva opzione.

I protocolli descritti sopra, tuttavia, hanno una finestra - cioè, quanti pacchetti invia il mittente in una volta? Il che significa che hai bisogno di una sorta di finestratura, ma non per il controllo del flusso. Come trasmetti le dimensioni della finestra?

Si potrebbe fare senza una finestra avendo la dimensione della finestra costante, o facendo qualcosa come stop-and-wait. Il primo potrebbe essere un'opzione migliore.

In ogni caso, non ho risposto direttamente alla tua domanda, ma spero di aver indicato alcune delle cose che vale la pena considerare quando si tratta di progettare questo. Il compito di avere un "trasferimento affidabile" senza parti del controllo di flusso (come i finestrini) e senza alcun riguardo per l'ordine è difficile! (Fatemi sapere se dovrei dare maggiori dettagli su alcune di queste cose!)

Buona fortuna!

0

Il modo migliore per implementare Ack è farlo nel livello applicazione. CoAP è un esempio di un protocollo applicativo che gira su udp ma fornisce un trasferimento dati affidabile. Mantiene un messaggio id per tutti i messaggi confermati (CON) e invia un ricevitore invia un pacchetto ack con lo stesso ID messaggio. Tutti i campi ACK e ID messaggio vengono mantenuti nella parte del livello applicazione. Quindi, se il mittente non riceve un pacchetto Ack con l'ID messaggio inviato da lui, trasmette nuovamente quel pacchetto. Lo sviluppatore dell'applicazione può modificare il protocollo in base alle esigenze richieste per un trasferimento affidabile dei dati.