Trasferimento file TCP asincrono

0

Ho un trasferimento di file asincrono usando boost::asio .
Più file possono essere trasferiti allo stesso tempo. La stessa ora del pacchetto in-file per il file 1, il prossimo pacchetto per il file 3, successivo per il file 2, ... Nessun trasferimento di file con thread nello stesso socket.

Attualmente invio ogni volta un pacchetto / messaggio / stringa da 10KB, inclusa una piccola intestazione con OPCode, un GUID, ecc., dal mittente al ricevente. Quando il ricevitore ha ricevuto il pacchetto invierà un piccolo pacchetto di riconoscimento (~ 20byte + - 4) al mittente. Quando il mittente ha ricevuto il pacchetto, invierà il pacchetto successivo per il file corrispondente al ricevitore e verrà riavviato.

La mia domanda è, se questo sembra un approccio ragionevole, o se ce n'è uno migliore.
Nota a margine: userò anche una libreria zip in seguito per inviare più / meno dati per pacchetto.
Prima di usare questo "stile" ho solo continuato a "spammare" tutti i pacchetti dal lato del mittente al lato del destinatario senza alcun riconoscimento. I "pacchetti" / messaggi vengono suddivisi e pertanto l'applicazione non riconosce i dati in entrata (senza intestazione) come validi e li elimina. Ciò significa fondamentalmente che i dati vengono persi dal lato dei ricevitori.

Che cosa consiglieresti, qual è l'approccio migliore per inviare dati velocemente su una connessione TCP (opt. SSL troppo), supponendo che entrambe le estremità abbiano tassi di upload / download diversi?

Se hai bisogno di ulteriori informazioni su qualcosa di specifico, lascia un commento.

Modifica:

Come invio più file, i miei "pacchetti" / messaggi includono, come menzionato sopra un GUID nell'intestazione. È possibile trasferire più file contemporaneamente. L'invio di dati di grandi dimensioni, ad esempio 5 MB, spesso divide il messaggio, e ciò significa che ai messaggi senza l'intestazione arriva, e quindi interrompe il sistema.

Una soluzione facile sarebbe quella di ri-strutturare il mio codice un po 'e inviare file per file. Ciò funzionerebbe se l'intestazione fosse inviata una volta, e subito dopo il data- / filechunk fosse inviato senza intestazione in pacchetti più grandi. Come detto bЈовић , TCP si prenderà cura di tutto il resto.

Nella mia attuale "soluzione" / approccio ho purtroppo bisogno del menzionato "sistema" che ho spiegato. Per altri trasferimenti tranne questo, sto inviando file per file e i dati sono divisi .

    
posta Blacktempel 19.08.2016 - 06:43
fonte

2 risposte

1

La domanda è ancora un po 'vaga, ma sembra che TCP stia facendo il suo lavoro e che fornisca byte nella sequenza esatta in cui sono stati inviati.

Mi chiedo se hai inviato di byte nel canale da più di un thread. In tal caso è perfettamente possibile che si verifichi quanto segue:

  1. Il thread A tenta di inviare N byte attraverso il socket. (N > 1).
  2. Il buffer è pieno, il socket accetta M byte. Quindi il thread A dovrà tentare nuovamente la trasmissione dei byte N-M.
  3. Prima di riprovare la trasmissione, il thread A perde la CPU.
  4. Il thread B ottiene la CPU.
  5. Nel frattempo, alcuni dati sono stati trasmessi con successo, quindi il socket ha spazio disponibile nei suoi buffer.
  6. Sarebbe ora possibile per il thread A inviare i restanti N-M byte. Ma il thread A non ha la CPU, quindi non invia niente.
  7. Il thread B tenta di inviare alcuni byte a sé stanti. Diciamo che invia X byte.
  8. I buffer con spazio disponibile, il socket accetta quei byte.
  9. Il thread B perde la CPU.
  10. Il thread A ottiene la CPU.
  11. Nel frattempo, alcuni dati sono stati trasmessi con successo, quindi il socket ha spazio disponibile nei suoi buffer.
  12. Il thread A ora è in grado di inviare i restanti N-M byte. E lo fa.

Sul lato ricevente, i byte che arrivano saranno M byte dal thread A; X byte dal thread B; e N-M bytes dal thread A. Penso che questo sia ciò che intendi per "split packets".

L'unico modo per essere certi di evitare pacchetti divisi è se la dimensione del pacchetto è 1 byte. Nessun'altra "dimensione del pacchetto" (come quella che hai provato) eliminerà la possibilità di divisioni: riduce solo le possibilità.

Devi essere sicuro che ogni canale TCP abbia un solo thread che lo alimenta. Il modo in cui lo faccio è che tutti i thread di trasmissione non inviino i dati direttamente al socket. Aggiungono tutti i loro pacchetti a una coda e un singolo thread di trasmettitore prende un pacchetto dalla coda, lo trasmette, prende il pacchetto successivo dalla coda, lo trasmette e così via. Non ci sono quindi divisioni.

Nessun modello di riconoscimento è necessario dall'altra parte, perché non è la causa del tuo problema.

    
risposta data 19.08.2016 - 14:13
fonte
0

Dipende tutto dal protocollo che hai stabilito. Non hai fornito molti dettagli, ma presumo che il mittente non abbia realmente bisogno di quei pacchetti di ritorno e che richieda solo un grande blob di dati.

Se le mie supposizioni sono corrette, devi solo inviare un intero blob di dati contemporaneamente. Il protocollo TCP si prenderà cura del riposo. Se fallisce per qualsiasi motivo, l'implementazione di boost ti dirà cosa è successo.

    
risposta data 19.08.2016 - 09:44
fonte

Leggi altre domande sui tag