Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi IdFTP -> Downloadgeschwindigkeit begrenzen (Indy 10) (https://www.delphipraxis.net/87121-idftp-downloadgeschwindigkeit-begrenzen-indy-10-a.html)

CK_CK 23. Feb 2007 15:10


IdFTP -> Downloadgeschwindigkeit begrenzen (Indy 10)
 
Hallo,
wie bereits im Titel zu sehen, würde ich gerne wissen, wie man die Downloadgeschwindigkeit einer TIdFTP-Komponente beschränken kann (z.B. mit max. 200 kb/s downloaden, obwohl 600 möglich wären).

Ich habe auch schon danach gesucht, aber nirgends eine Lösung gefunden. Ist das überhaupt mit Indy möglich?
Wenn nein: Gibt es andere Komponenten, die das können?

Vielen Dank schonmal für eure Antworten :angel2:,
Chris

SirThornberry 23. Feb 2007 15:20

Re: IdFTP -> Downloadgeschwindigkeit begrenzen (Indy 10)
 
die Komponente selbst bietet es nicht ABER du kannst es erzwingen wenn du den Stream in den geladen wird dazu bringst die Daten nur in einer bestimmten Geschwindigkeit entgegen zu nehmen. Wenn du also beim schreiben in den Stream festgestellt wird das noch gar keine Daten wieder rein dürften weil sonst die Datenrate zu hoch wird wartest du mit dem schreiben bis die Zeit reif ist.

CK_CK 23. Feb 2007 15:26

Re: IdFTP -> Downloadgeschwindigkeit begrenzen (Indy 10)
 
Hi!
Vielen Dank für die Idee! Wie bringe ich denn den Stream dazu, keine Daten anzunehmen?
Ich verwende IdFtp.Get('Adresse', aSTREAM);. Ich kann doch während die FTP-Komponente in den Stream schreibt nicht auch noch den Stream bearbeiten, oder?

Chris

SirThornberry 23. Feb 2007 16:56

Re: IdFTP -> Downloadgeschwindigkeit begrenzen (Indy 10)
 
du leitest einfach von deiner Streamklasse ab und überschreibst die Funktion "Write", in der Funktion lässt du eine schleife laufen die solange läuft bis das schreiben wieder erlaubt ist. Wann das schreiben erlaubt ist musst du aus den Datenmengen errechen. Wenn du also 3kb pro Sekunden zulässt und deiner Funktion 6kb übergeben werden darfst du erst nach 2 Sekunden wieder neue Daten zulassen bzw. die Funktion 1 Sekunde blockieren.
Delphi-Quellcode:
procedure TYourStream.Write(const Buffer; Count: Longint): Longint;
begin
  while not(NeueDatenErlaubt()) do
  begin
    //Das Sleep ist geschmackssache
    sleep(10);
  end;
  inherited;
end;

CK_CK 23. Feb 2007 18:22

Re: IdFTP -> Downloadgeschwindigkeit begrenzen (Indy 10)
 
Ich hab' das so mal probiert, aber irgendwie funktioniert es nicht.
Ich bekomme immer eine AV "Ungültige Gleitkommaoperation"...

Mein Code sieht so aus:
Delphi-Quellcode:
type
  TSpeedLimitedStream = class(TFileStream)
  private
    fMaxSpeed: Cardinal;
    fLastTick: Cardinal;
    fLastCount: Integer;

    function NewDataAllowed(Count: Integer): Boolean;
  public
    function Write(const Buffer; Count: Longint): Longint; override;

    property MaxSpeed: Cardinal read fMaxSpeed write fMaxSpeed default 0;
  end;
Implementiert habe ich die Methoden so:
Delphi-Quellcode:
function TSpeedLimitedStream.NewDataAllowed(Count: Integer): Boolean;
var
  curTick: Cardinal;
  curCount: Integer;
begin
  if fMaxSpeed = 0 then
  begin
    Result := True;
  end else begin
    curTick := GetTickCount;
    curCount := Count;

    if (curCount-fLastCount)/((curTick-fLastTick)/1000) <= fMaxSpeed then
      Result := False
    else
      Result := True;

    fLastTick := GetTickCount;
    fLastCount := Count;
  end;
end;

function TSpeedLimitedStream.Write(const Buffer; Count: Integer): Longint;
begin
  while not NewDataAllowed(Count) do
    Sleep(10);

  inherited Write(Buffer, Count);
end;
Ich benutze diesen Stream ganz normal für's downloaden, also IdFTP.Get('Dateiname', MyStream);, wobei MyStream vom Typ TSpeedLimitedStream ist und MaxSpeed auf 50 gesetzt ist...

Erkennt jemand daran einen Fehler?

Chris

CK_CK 23. Feb 2007 19:37

Re: IdFTP -> Downloadgeschwindigkeit begrenzen (Indy 10)
 
Da war ein ganz großer Denkfehler drinnen... :oops:

Für alle, die auch mal sowas machen wollen kommt hier der berichtigte Code:
Interface:
Delphi-Quellcode:
type
  TSpeedLimitedStream = class(TFileStream)
  private
    fMaxSpeed: Cardinal;
    fLastTick: Cardinal;

    function NewDataAllowed(Count: Longint): Boolean;
  public
    function Write(const Buffer; Count: Longint): Longint; override;

    property MaxSpeed: Cardinal read fMaxSpeed write fMaxSpeed default 0;
  end;
Implementation:
Delphi-Quellcode:
function TSpeedLimitedStream.NewDataAllowed(Count: Integer): Boolean;
var
  tmp: Cardinal;
begin
  tmp := GetTickCount-fLastTick;
  if tmp = 0 then tmp := 1;
  Result := Count/tmp <= fMaxSpeed;
end;

function TSpeedLimitedStream.Write(const Buffer; Count: Longint): Longint;
begin
  if fMaxSpeed > 0 then
    while not NewDataAllowed(Count) do
      Sleep(1);
  fLastTick := GetTickCount;

  Result := inherited Write(Buffer, Count);
end;
So funktioniert das perfekt! Vielen Dank nochmal an SirThornberry! :thumb:

Einen schönen Abend noch,
Chris

SirThornberry 23. Feb 2007 19:39

Re: IdFTP -> Downloadgeschwindigkeit begrenzen (Indy 10)
 
Schön zu wissen das meine theoretichen Gedanken praktich funktioneren, hab nie die zeit gefunden das auch mal zu probieren - danke :-D


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:03 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz