Entwickler-Ecke

Internet / Netzwerk - Geschwindigkeit der Datenübertragung...


hibbert - Do 10.06.04 19:23
Titel: Geschwindigkeit der Datenübertragung...
Hi,
ich übertrage Daten mithilfe der Indykomponenten TPCServer u. Client (Stream). Nun möchte ich gerne wissen, wie schnell die Daten übertragen werden.

Dazu möchte ich noch wiessen, wie lange es ungefähr dauert, bis die Daten vollständig übertragen sind.

thx hibbert


DaRkFiRe - Do 10.06.04 23:18

Zum Anfang der Datenuebertragung holste Dir den aktuellen Timestamp (GetTickCount). Zum Zeitpunkt einer Zeitmessung holst Du Dir einen neuen Timestamp und berechnest Die Differenz.

Nun ist Transferierte_Datenmenge/ZeitDifferenz_in_Sekunden gleich Deine Uebertragungsgeschwindigkeit. Willst Du wissen, wieviel Zeit noch zur vollstaendigen Uebertragung bleibt, musst Du Gesamtdatenmenge_minus_uebertragene_Datenmenge/Uebertragungsgeschwindigkeit_in_Sekunden rechnen und schon haste die verbleibende Zeit in Sekunden.


hibbert - Fr 11.06.04 19:32

nun gut, soweit hab ich es ja auch verstanden, doch wie komme ich an diese Daten ran?

Wie das mit dem Timestamp ist, hast du ja schon geschrieben... wie bekomme ich jetzt raus, wieviel von der Datei schon übertragen wurde?

Und was ist bei
Zitat:
Transferierte_Datenmenge/ZeitDifferenz_in_Sekunden
mit
ZeitDifferenz_in_Sekunden gemeint?

thx hibbert


maxk - Sa 12.06.04 09:48

Die Clientkomponente hat die Ereignisse OnWorkBegin, OnWork und OnWorkEnd. Diesen Events werden Größe der Datenmenge und bereits transferierte Datenmenge übermittelt.
hibbert hat folgendes geschrieben:
Und was ist bei
Zitat:
Transferierte_Datenmenge/ZeitDifferenz_in_Sekunden
mit
ZeitDifferenz_in_Sekunden gemeint?

thx hibbert
ZeitDifferzent_in_Sekunden=(AktuellerTimestamp-AlterTimestamp) div 1000; // Timestamps sind in ms


hibbert - Sa 12.06.04 17:58

ok, danke, doch in der Procedure

Delphi-Quelltext
1:
2:
procedure TForm1.ClientWorkBegin(Sender: TObject; AWorkMode: TWorkMode;
  const AWorkCountMax: Integer);

ist AWorkCountMax sicherlich die Dateigröße, doch diese größe ist bei mir immer 0, warum?

und das mit der verbleibenden Zeit stimmt auch nicht so ganz:

Delphi-Quelltext
1:
2:
3:
aktuellertimestamp:=GetTickCount;
statusbar1.Panels[1].Text:=inttostr((AktuellerTimestamp-AlterTimestamp) div 1000);
altertimestamp:=GetTickCount;


Diese Procedure hatte ich bereits in einem Timer und in der Procedure OnWork des Clieneten drin...
als ergebnis erhalte ich immer nur eine 1 oder eine 0....

thx hibbert


maxk - Sa 12.06.04 18:31

hibbert hat folgendes geschrieben:
ok, danke, doch in der Procedure

Delphi-Quelltext
1:
2:
procedure TForm1.ClientWorkBegin(Sender: TObject; AWorkMode: TWorkMode;
  const AWorkCountMax: Integer);

ist AWorkCountMax sicherlich die Dateigröße, doch diese größe ist bei mir immer 0, warum?
AThread.Connection.WriteStream(Stream,True,True);
Das dritte True teilt dem Client vorher mit, wieviele Bytes auf ihn warten. Ich hab's allerdings lange nicht mehr gemacht - garantieren kann ich für nix.


hibbert - Sa 12.06.04 20:14

mhh, das ist immernoch 0 :?
irgentwie funzt das noch nicht....

hibbert


maxk - So 13.06.04 09:30

Poste doch mal bitte ein wenig Quellcode.


hibbert - So 13.06.04 13:10

ok, kein problem:Client

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
var
  Form1: TForm1;
  AktuellerTimestamp,AlterTimestamp:integer;

implementation

{$R *.dfm}

procedure TForm1.Button2Click(Sender: TObject);
begin

    try
      Client.Connect(15000);  // in Indy < 8.1 leave the parameter away
      button1.Enabled:=true;
      button2.Enabled:=false;
    except
      on E: Exception do
        MessageDlg ('Fehler beim Verbinden:'#13+
                     E.Message, mtError, [mbOk], 0);
    end;


end;

procedure TForm1.Button1Click(Sender: TObject);
var
  FStream: TFileStream;
begin
//showmessage(inttostr(GetTickCount));
button2.Enabled:=true;
button1.Enabled:=false;
animate1.Visible:=true;
  FStream := TFileStream.Create('C:\client.tmp', fmCreate);
  try
    Client.ReadStream(FStream, -1, True); // Stream empfangen
    FStream.Seek(0, soFromBeginning);
  finally
    FStream.Free; // Stream freigeben
  end;
end;
procedure TForm1.ClientStatus(ASender: TObject; const AStatus: TIdStatus;
  const AStatusText: String);
begin
statusbar1.Panels[0].Text:=astatustext;
end;

procedure TForm1.ClientWork(Sender: TObject; AWorkMode: TWorkMode;
  const AWorkCount: Integer);
begin
try
progressbar1.Position:=strtoint(button1.Caption);
except
beep;
end;
button1.Caption:=inttostr(aworkcount);
aktuellertimestamp:=GetTickCount;
statusbar1.Panels[1].Text:=inttostr((AktuellerTimestamp-AlterTimestamp) div 1000);
altertimestamp:=GetTickCount;
end;

procedure TForm1.ClientWorkBegin(Sender: TObject; AWorkMode: TWorkMode;
  const AWorkCountMax: Integer);
begin
altertimestamp:=GetTickCount;
progressbar1.Max:=AWorkCountMax;
button2.Caption:=inttostr(AWorkCountMax);
end;

procedure TForm1.ClientWorkEnd(Sender: TObject; AWorkMode: TWorkMode);
begin
statusbar1.Panels[0].Text:='Übertragung erfolgreich. -- Verbindung getrennt --';
end;

Server:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
  FStream: TFileStream;
begin
  FStream := TFileStream.Create('d:\test.zip', fmOpenRead);
  try
    AThread.Connection.OpenWriteBuffer;
    AThread.Connection.WriteStream(FStream,true,true);
    AThread.Connection.CloseWriteBuffer;
  finally
    AThread.Connection.Disconnect;
    FStream.Free;
  end;
end;


hibbert


maxk - Mi 16.06.04 15:16

Schreib doch mal in Codezeile 35 des Clients nur Client.ReadStream(FStream);. Dann sollte eigentlich alles funktionieren. Nun muss ReadStream den WorkCountMax auslesen, um zu wissen, wann es reicht ;)
Noch ein Tipp, wenn du Zeile 7 und 9 des Servers weglässt, sparen Server und Client ein wenig Zeit.


hibbert - Mi 16.06.04 16:50

ok, das mit der progressbar funzt jetzt, aber die "wie lange es noch dauert" Anzeige funzt noch net :cry:

Was ist denn an meiner Rechnung falsch?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
var  
  Form1: TForm1;  
  AktuellerTimestamp,AlterTimestamp:integer;  

 
implementation  

 
{$R *.dfm}  

 
procedure TForm1.Button2Click(Sender: TObject);  
begin  

 
    try  
      Client.Connect(15000);  // in Indy < 8.1 leave the parameter away  
      button1.Enabled:=true;  
      button2.Enabled:=false;  
    except  
      on E: Exception do  
        MessageDlg ('Fehler beim Verbinden:'#13+  
                     E.Message, mtError, [mbOk], 0);  
    end;  

 

 
end;  

 
procedure TForm1.Button1Click(Sender: TObject);  
var  
  FStream: TFileStream;  
begin  
//showmessage(inttostr(GetTickCount));  
button2.Enabled:=true;  
button1.Enabled:=false;  
animate1.Visible:=true;  
  FStream := TFileStream.Create('C:\client.tmp', fmCreate);  
  try  
    Client.ReadStream(FStream, -1); // Stream empfangen  
    FStream.Seek(0, soFromBeginning);  
  finally  
    FStream.Free; // Stream freigeben  
  end;  
end;  
procedure TForm1.ClientStatus(ASender: TObject; const AStatus: TIdStatus;  
  const AStatusText: String);  
begin  
statusbar1.Panels[0].Text:=astatustext;  
end;  

 
procedure TForm1.ClientWork(Sender: TObject; AWorkMode: TWorkMode;  
  const AWorkCount: Integer);  
begin  
try  
progressbar1.Position:=strtoint(button1.Caption);  
except  
beep;  
end;  
button1.Caption:=inttostr(aworkcount);  
aktuellertimestamp:=GetTickCount;  
statusbar1.Panels[1].Text:=inttostr((AktuellerTimestamp-AlterTimestamp) div 1000);  
altertimestamp:=GetTickCount;  
end;  

 
procedure TForm1.ClientWorkBegin(Sender: TObject; AWorkMode: TWorkMode;  
  const AWorkCountMax: Integer);  
begin  
altertimestamp:=GetTickCount;  
progressbar1.Max:=AWorkCountMax;  
button2.Caption:=inttostr(AWorkCountMax);  
end;  

 
procedure TForm1.ClientWorkEnd(Sender: TObject; AWorkMode: TWorkMode);  
begin  
statusbar1.Panels[0].Text:='Übertragung erfolgreich. -- Verbindung getrennt --';  
end;


thx hibbert


maxk - Do 17.06.04 14:45

Schreib mal zwischen Zeile 65 und 66 noch ein Application.ProcessMessages;.