Domanda

Si supponga di avere un programma che legge da una presa.Come si fa a mantenere la velocità di download al di sotto di una certa soglia prefissata?

È stato utile?

Soluzione

A livello di applicazione (Berkeley socket stile API), puoi solo guardare l'orologio, e leggere o scrivere dati al tasso che si desidera limitare al.

Se leggi 10kbps in media, ma la fonte è l'invio di più, quindi alla fine tutti i buffer tra esso e si riempirà.TCP/IP consente per questo, e il protocollo organizza per il mittente di rallentare (a livello di applicazione, probabilmente tutto quello che dovete sapere è che all'altra estremità, il blocco di scrittura chiamate di blocco, non scrive avrà esito negativo e la scrittura asincrona non completa, fino a quando hai letto un numero sufficiente di dati per consentire di esso).

A livello applicativo si può essere solo approssimativa, non può garantire dei limiti rigidi come "non più di 10 kb e passare un determinato punto della rete in qualsiasi un secondo".Ma se si tenere traccia di quello che hai ricevuto, è possibile ottenere la media di destra nel lungo periodo.

Altri suggerimenti

Ipotizzando una rete di trasporto, TCP/IP di base, i Pacchetti vengono inviati in risposta a ACK/NACK i pacchetti che vanno in altra direzione.

Limitando il tasso di pacchetti, attestante la ricezione dei pacchetti che, a sua volta, ridurre il tasso al quale i nuovi pacchetti vengono inviati.

Può essere un po ' imprecisa, quindi forse il suo ottimale per monitorare il downstream e regolare il tasso di risposta adattativa fino a quando non cade all'interno di un confortevole soglia.( Questo avverrà molto rapidamente tuttavia, è possibile inviare dosens di ack di un secondo )

È come quando si limita a un gioco di un certo numero di FPS.

extern int FPS;
....    
timePerFrameinMS = 1000/FPS;

while(1) {
time = getMilliseconds();
DrawScene();
time = getMilliseconds()-time;
if (time < timePerFrameinMS) {
   sleep(timePerFrameinMS - time);
}
}

In questo modo si è sicuri che il gioco la frequenza di aggiornamento sarà al massimo di FPS.Allo stesso modo DrawScene può essere la funzione di pompa il byte nel flusso di socket.

Se stai leggendo da una presa, tu non hai il controllo della larghezza di banda utilizzata - stai leggendo il sistema operativo del buffer del socket, e nulla si dice renderà la persona di scrittura per la scrittura di socket meno di dati (a meno che, naturalmente, hai elaborato un protocollo per l').

Tutti che la lettura lentamente vorresti fare è riempire il buffer, e la causa di un eventuale stallo sulla rete end - ma tu non hai il controllo di come e quando questo accade.

Se vuoi davvero leggere solo così tanto di dati alla volta, si può fare qualcosa di simile a questo:

ReadFixedRate() {
  while(Data_Exists()) {
    t = GetTime();
    ReadBlock();
    while(t + delay > GetTime()) {
      Delay()'
    }
  }
}

wget sembra gestire con il-limite-tasso di opzione.Ecco la pagina man:

Nota che Wget implementa la limitazione dormendo una quantità appropriata di tempo dopo una lettura in rete che ha preso meno tempo di quanto specificato dal tasso di.Alla fine, questa strategia cause il trasferimento TCP rallentare per circa la frequenza specificata.Tuttavia, può richiedere un certo tempo per questo equilibrio per essere realizzato, in modo da non essere sorpreso se la limitazione della velocità non funziona bene con molto piccolo i file.

Come altri hanno detto, il kernel del sistema operativo è la gestione del traffico e si sono semplicemente leggendo una copia dei dati della memoria del kernel.A circa limitare il tasso di una sola applicazione, è necessario ritardare le letture dei dati e consente la ricezione di pacchetti di buffer del kernel, che finirà per rallentare il riconoscimento dei pacchetti in entrata e ridurre il tasso che una presa di corrente.

Se si vuole rallentare il traffico della macchina, è necessario regolare le dimensioni del vostro arrivo buffer TCP.In Linux, si potrebbe influenzare questo cambiamento, modificando i valori in /proc/sys/net/ipv4/tcp_rmem (leggere la memoria dimensioni di buffer) e altri tcp_* i file.

Per aggiungere a Branan risposta:

Se decidi volontariamente di limitare la velocità di lettura del destinatario, alla fine, le code si riempie a entrambe le estremità.Quindi il mittente blocco nella sua chiamata send() o di ritorno dalla chiamata send() con un sent_length meno del previsto lunghezza passato alla chiamata send ().

Se il mittente non è pronto per affrontare questo caso, dormendo e cercando di inviare di nuovo che non si adattano in OS buffer, è di finire hanno problemi di connessione (il mittente può rilevare come errore) o la perdita di dati (il mittente può inconsapevolmente eliminare i dati che non rientrano in OS buffer).

Impostare piccola presa di inviare e ricevere buffer, diciamo 1k o 2k, in modo tale che la larghezza di banda*ritardo di prodotto = la dimensione del buffer.Potrebbe non essere in grado di ottenere abbastanza piccolo su collegamenti veloci.

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