Come è stato sottolineato nei commenti, non si può fare questo abbastanza bene da dare garanzie. Ma, supponiamo che tu voglia fare del tuo meglio, comunque.
ci sono due parti a questo problema:
- determinare la larghezza di banda disponibile.
- Controlla la larghezza di banda consumata.
Il controllo approssimativo dell'ampiezza di banda consumata può essere eseguito in un programma spaziale utente limitando la velocità di lettura dal socket. Lo stack TCP/IP notificherà l'altra estremità della connessione che la coda sta mantenendo per conto della tua applicazione è diventata piena e non verrà inviato altro. Un modo conveniente per implementare tale limitazione è con token buckets.
rapida implementazione token secchio:
int bucket = 0;
start_thread({ while(transfer_in_progress) {
bucket += bytes_per_second_limit;
sleep(1);
});
while(transfer_in_progress) {
bytesread = read(socket, buffer, min(bucket, buffersize),);
bucket -= bytesread;
}
Se bytes_per_second_limit
è impostato a circa la larghezza di banda disponibile, espressa in byte/secondo, che poi dovrebbe leggere più velocemente il collegamento consente. Se la connessione è più veloce, sarai limitato a bytes_per_second_limit
. Se la connessione è più lenta, allora bucket
crescerà per sempre, ad una velocità proporzionale alla differenza tra il limite di velocità e la larghezza di banda disponibile.
Hmm!
Se si esegue un altro thread, e tenere d'occhio bucket
, è possibile guardare per due condizioni:
- Se
bucket
è sempre 0, allora non v'è più larghezza di banda disponibile, e si può aumentare bytes_per_second_limit
, limitata forse dalla tua ipotesi più recente per la larghezza di banda disponibile (dal n. 2). Oppure avviare un download aggiuntivo.
- Se
bucket
è più grande dell'ultima volta che hai guardato, e gli ultimi secondi di punti di dati sembrano indicare una crescita continua (magari fare una regressione lineare, qualunque cosa tu voglia), la velocità di quella crescita espressa in byte/secondo è quanto è possibile ridurre bytes_per_second_limit
per adeguare la velocità di download con la larghezza di banda disponibile.
Il problema con tutto questo è che non vi è alcuna garanzia che la larghezza di banda rimarrà costante.Il monitoraggio del thread bucket
potrebbe rimbalzare avanti e indietro tra l'aumento della velocità e la limitazione. Ti suggerisco di iniziare con una media di almeno 10 o 20 secondi prima di apportare modifiche al limite di velocità.
fonte
2015-04-29 21:03:14
Per sapere in anticipo la velocità di download totale? –
@ PetrPudlák Io no. – PyRulez
@PyRulez Quindi questo non sarà un semplice problema da risolvere. Dovrai avviare i download individualmente fino a quando non raggiungi un limite, il che significa che dovrai decidere cosa significa colpire un cap. A quel punto conoscerai la tua larghezza di banda, ma conoscere la velocità DL di ogni oggetto sarà più difficile. Se provengono tutti dallo stesso server e hanno all'incirca la stessa velocità DL, allora puoi semplicemente calcolare la media e assumerti, ma se sono tutti diversi, sarà un atto di bilanciamento più difficile. – bheklilr