Domanda

Sto scrivendo un'app client-server utilizzando i socket BSD. Deve essere eseguito in background, trasferendo continuamente dati, ma non può limitare la larghezza di banda dell'interfaccia di rete dall'uso normale. A seconda della velocità dell'interfaccia, devo limitare questa connessione a una determinata velocità di trasferimento massima.

Qual è il modo migliore per raggiungere questo obiettivo, a livello di codice?

È stato utile?

Soluzione

Il problema con la sospensione di una quantità costante di 1 secondo dopo ogni trasferimento è che si avranno prestazioni di rete discordanti.

Lascia che BandwidthMaxThreshold sia la soglia di larghezza di banda desiderata.

Consenti a TransferRate di essere la velocità di trasferimento corrente della connessione.

Quindi ...

Se rilevi TransferRate > BandwidthMaxThreshold, quindi esegui SleepTime = 1 + SleepTime * 1.02 (aumenta il tempo di inattività del 2%)

Prima o dopo ogni operazione di rete fare a Sonno (SleepTime)

Se rilevi che TransferRate è molto più basso di BandwidthMaxThreshold, puoi ridurre il tuo SleepTime. In alternativa, puoi semplicemente decadere / ridurre il tuo SleepTime nel tempo sempre. Alla fine il tuo SleepTime raggiungerà di nuovo 0.

Invece di un aumento del 2% potresti anche fare un aumento di una quantità maggiore linearmente della differenza tra TransferRate - BandwidthMaxThreshold.

Questa soluzione è buona, perché non avrai dormi se la rete dell'utente non è già alta come vorresti.

Altri suggerimenti

Il modo migliore sarebbe utilizzare un bucket token .

Trasmetti solo quando hai abbastanza token per riempire un pacchetto (1460 byte sarebbe una buona quantità), o se sei il lato di ricezione, leggi dal socket solo quando hai abbastanza token; un po 'di matematica semplice ti dirà quanto devi aspettare prima di avere abbastanza token, in modo da poter dormire quel periodo di tempo (fai attenzione a calcolare quanti token hai guadagnato da quanto effettivamente dormito, poiché la maggior parte dei sistemi operativi può sospendere il processo più a lungo di quanto richiesto).

Per controllare la dimensione degli scoppi, limita la quantità massima di token che puoi avere; una buona quantità potrebbe essere un secondo di gettoni.

Ho avuto fortuna con trickle . È interessante perché può limitare le applicazioni di spazio utente arbitrarie senza modifiche. Funziona precaricando le proprie funzioni wrapper send / recv che eseguono il calcolo della larghezza di banda per te.

Il più grande svantaggio che ho riscontrato è che è difficile coordinare più applicazioni con cui si desidera condividere la larghezza di banda finita. & Quot; trickled " aiuta, ma l'ho trovato complicato.

Aggiornamento nel 2017: sembra che il gocciolamento sia stato spostato in https://github.com/mariusae/trickle

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