Frage

Angenommen, Sie haben ein Programm, das von einem Socket liest. Wie halten Sie die Downloadrate unter einem bestimmten vorgegebenen Schwellenwert?

War es hilfreich?

Lösung

Auf der Anwendungsschicht (mit einem Socket-Stil API Berkeley) Sie nur auf die Uhr, und lesen oder schreiben Daten mit einer Rate Sie beschränken möchten.

Wenn Sie nur 10kbps im Durchschnitt lesen, aber die Quelle ist mehr als das Senden, dann schließlich alle Puffer zwischen ihm und Sie füllen. TCP / IP für die dies ermöglicht, und das Protokoll organisiert für den Absender (auf der Anwendungsschicht zu verlangsamen, wahrscheinlich alles, was Sie wissen müssen, ist, dass Anrufe am anderen Ende, Blockieren von Schreib blockiert wird nonblocking schreibt fehlschlagen, und asynchrone schreibt nicht abgeschlossen werden, bis Sie es genügend Daten gelesen haben, ermöglichen).

Auf der Anwendungsebene können Sie nur eine ungefähre Angabe - Sie können nicht harten Grenzen garantieren wie „nicht mehr als 10 kb wird Sekunde einen bestimmten Punkt im Netzwerk in einem passieren“. Aber wenn Sie zu verfolgen, was Sie erhalten haben, können Sie die durchschnittliche rechts auf lange Sicht erhalten.

Andere Tipps

ein Netzwerk Transport Angenommen, ein TCP / IP-basierte ein, werden Pakete als Antwort gesendet ACK / NACK in die andere Richtung Pakete gehen.

die Rate der Pakete Durch die Begrenzung Empfang der eingehenden Pakete anerkennen, werden Sie wiederum reduzieren die Geschwindigkeit, mit der neuen Paketen gesendet werden.

Es kann ein wenig ungenau sein, so dass ihr möglicherweise optimal, um die Downstream-Rate zu überwachen und die Ansprechrate adaptiv, bis es sich in einer komfortablen Schwelle fällt einzustellen. (Dies geschieht sehr schnell aber Sie senden dosen von acks einer Sekunde)

Es ist wie wenn ein Spiel auf eine bestimmte Anzahl von FPS begrenzt wird.

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

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

So können Sie sicherstellen, dass das Spiel Bildwiederholfrequenz bei den meisten FPS sein wird. Auf die gleiche Weise kann die drawScene Funktion verwendet werden Bytes in die Buchse Strom zu pumpen.

Wenn Sie von einem Socket lesen, haben Sie keine Kontrolle über die verwendete Bandbreite - Sie lesen den Puffer des Betriebssystems dieser Buchse, und nichts, was Sie sagen, die Person machen an die Buchse schreiben Schreiben weniger Daten (es sei denn, , natürlich, Sie haben ein Protokoll für das ausgearbeitet).

, dass das Lesen langsam alle tun würde, um den Puffer aufzufüllen, und verursachen einen eventuellen Stall auf dem Netzwerk Ende - aber Sie haben keine Kontrolle darüber, wie oder wann dies geschieht

.

Wenn Sie wirklich nur so viele Daten auf einmal lesen möchten, können Sie etwas tun:

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

wget scheint es mit der --limit-Rate Option zu verwalten. Hier ist von der man-Seite:

  

Beachten Sie, dass Wget implementiert die Begrenzung   durch die entsprechende Menge von Schlaf   Zeit nach einem Netzwerk zu lesen, dass nahm   weniger Zeit als durch die Angabe   Bewertung. Schließlich diese Strategie Ursachen   die TCP-Übertragung zu verlangsamen   etwa die angegebene Rate.   Allerdings kann es einige Zeit dauern,   dieses Gleichgewicht erreicht werden, also nicht   werden überrascht die Rate, wenn Begrenzung   funktioniert nicht gut mit sehr kleinen   Dateien.

Wie andere schon gesagt haben, ist der OS-Kernel, den Verkehr Verwaltung und Sie sind einfach eine Kopie der Daten aus Kernel-Speicher zu lesen. Um etwa die Geschwindigkeit der Anwendung nur einer begrenzen, müssen Sie Ihr liest die Daten verzögern und damit eingehenden Paketen im Kernel puffern, die schließlich die Bestätigung der eingehenden Pakete verlangsamen werden und die Rate auf, dass eine Buchse reduzieren.

Wenn Sie den gesamten Datenverkehr an die Maschine verlangsamen wollen, müssen Sie die Größe Ihrer eingehenden TCP-Puffer gehen und zu justieren. In Linux, würden Sie diese Änderung beeinflussen, indem sie die Werte zu verändern in / proc / sys / net / ipv4 / tcp_rmem und anderen tcp_ * Dateien (Speicherpuffergrößen lesen).

Hinzufügen zu Branan Antwort:

Wenn Sie freiwillig die Lesegeschwindigkeit auf der Empfängerseite begrenzen, schließlich werden Warteschlangen an beiden Enden aufzufüllen. Dann wird der Sender entweder Block in seiner send () aufrufen, oder aus dem Sende zurückzukehren () mit einem sent_length geringer ist als die erwartete Länge auf das send () Aufruf übergeben.

Wenn der Sender nicht bereit ist, mit diesem Fall zu befassen, indem schlafen und versuchen, erneut zu senden, was nicht in OS Puffer passen hat, werden enden Sie auf Verbindungsprobleme haben (der Absender dies als Fehler erkennen kann) oder den Verlust von Daten (die Sender kann unwissentlich nicht in OS Puffer paßten Daten des verwerfen).

kleine Buchse Sende Set und Empfangspuffer, sagt 1k oder 2k, so dass die Bandbreite * Verzögerung Produkt = die Puffergröße. Sie können sie nicht klein genug, um über schnelle Verbindungen erhalten werden können.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top