AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi (Indy) TCPClient bekommt zuviel vom Server
Thema durchsuchen
Ansicht
Themen-Optionen

(Indy) TCPClient bekommt zuviel vom Server

Ein Thema von Harry M. · begonnen am 20. Apr 2006 · letzter Beitrag vom 21. Apr 2006
Antwort Antwort
Benutzerbild von Harry M.
Harry M.

Registriert seit: 29. Okt 2004
Ort: Halle
462 Beiträge
 
#1

(Indy) TCPClient bekommt zuviel vom Server

  Alt 20. Apr 2006, 19:08
Mahlzeit!

Ich möchte mit einem Indy TCPClient von einem Indy TCPServer eine Datei holen (was auch sonst ) Der Server sendet dabei (im Debugg-Modus) einen 2048 Byte grossen Stream an den Client dieser empfängt aber gleich mehr als die ganz Datei

Der Client;
Delphi-Quellcode:
procedure TDownloadThread.DownloadFile;
begin
  TCPClient := TIdTCPClient.Create(nil);
  TCPClient.Host := sHost;
  TCPClient.Port := iPort;

  try
    TCPClient.Connect(-1);
    except end;

  if TCPClient.Connected then begin
    TCPClient.WriteLn('GETSIZE='+sFileName);

    iRemoteFileSize := StrToInt(TCPClient.ReadLn);

    if iRemoteFileSize > 0 then begin
      TCPClient.WriteLn('GETFILE='+sFileName);

      fs := TFileStream.Create(sFileName + '.copy' ,fmCreate);
      ms := TMemoryStream.Create;

      sStatus := StatusWork;
      sProgress := IntToStr( Round(fs.Size/iRemoteFileSize*100) ) + '%';
      Synchronize(SyncProgress);

      while (TCPClient.Connected) and (fs.Size < iRemoteFileSize) do begin
       ms.Clear;

       try
        TCPClient.ReadStream(ms); // hier sollte er immer nur 2048 bzw den Rest bekommen, tut er aber nicht :-(
        except end;

        if ms.Size > 0 then
          fs.CopyFrom(ms, 0);

        sProgress := IntToStr( Round(fs.Size/iRemoteFileSize*100) ) + '%';
        Synchronize(SyncProgress);
        end;

      FreeAndNil(fs);
      FreeAndNil(ms);
      end;

    end;

  sStatus := StatusDone;
  Synchronize(SyncProgress);
  TCPClient.Free;
end;
Der Server, welcher meiner Meinug nach läuft:
Delphi-Quellcode:
procedure TVPumper.IdTCPServer1Execute(AThread: TIdPeerThread);
var
  fs: TFileStream;
  ms: TMemoryStream;
  I: Integer;
  iBytes2Send: Cardinal;
  S, sCommand, sFileName, sHash: String;
  slFileList: TStringList;
begin
  S := UpperCase(AThread.Connection.ReadLn);

  slFileList := TStringList.Create;

  sCommand := Copy(S, 1, 7);
  sFileName := Copy(S, 9, Length(S));

  // Dateiliste erstellen
  if sCommand = 'GETLISTthen begin
    if CreateFileList(ShreadFolder + '*.*', sFileName, slFileList) then
      slFileList.Text := StringReplace(slFileList.Text, '', '', [rfReplaceAll]);
      AThread.Connection.WriteLn(slFileList.Text);
      AThread.Connection.Disconnect;
    end;
                       
  if sCommand = 'GETSIZEthen begin

    sHash := Copy(S, 9, Length(S));

    if CreateFileList(ShreadFolder + '*.*', sHash, slFileList) then begin
      I := Pos('|', slFileList.Text) + 1;
      slFileList.Text := Copy(slFileList.Text, I, Length(slFileList.Text));

      I := Pos('|', slFileList.Text) - 1;
      slFileList.Text := Copy(slFileList.Text, 1, I);

      AThread.Connection.WriteLn(slFileList.Text);
      //AThread.Connection.Disconnect;
      end;

    end;

  if sCommand = 'GETFILEthen begin
    sHash := Copy(S, 9, Length(S));
    sFileName := Hash2File(sHash);

    fs := TFileStream.Create(sFileName ,fmOpenRead   + fmShareDenyNone);
    ms := TMemoryStream.Create;

    while fs.Position < fs.Size do begin
      ms.Clear;

      iBytes2Send := fs.Size - fs.Position;

      if iBytes2Send > 2048 then
        iBytes2Send := 2048;

      ms.CopyFrom(fs, iBytes2Send);

      AThread.Connection.OpenWriteBuffer;
      AThread.Connection.WriteStream(ms, True, True); // immer fleißig 2048 schauffeln, bzw den Rest
      AThread.Connection.CloseWriteBuffer;

      end;

    AThread.Connection.Disconnect;
    FreeAndNil(fs);
    FreeAndNil(ms);
    end;

  slFileList.Free;
end;
Wo liegt der Fehler (ausser im Detail ) ?
Harry
Gruß Harry
www.H-Soft.info
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#2

Re: (Indy) TCPClient bekommt zuviel vom Server

  Alt 20. Apr 2006, 19:34
Hallo Harry,

ich glaube der Fehler liegt im Konzept - ohne ein handshaking protocol schickt der Server alles auf einmal, auch wenn du den send buffer immer erst bei einer water mark von 2048 frei gibst.

Grüße vom marabu
  Mit Zitat antworten Zitat
Benutzerbild von Harry M.
Harry M.

Registriert seit: 29. Okt 2004
Ort: Halle
462 Beiträge
 
#3

Re: (Indy) TCPClient bekommt zuviel vom Server

  Alt 20. Apr 2006, 19:37
Hallo Marabu!

Im Demo Projekt, welches ich mir zum besseren Verständnis des Problems gemacht habe (s. Anhang) geht alles einwandfrei. Basiert auf der gleichen Technik.
Angehängte Dateien
Dateityp: rar tcp__bertragen__teilstream__-_geht_478.rar (199,9 KB, 13x aufgerufen)
Harry
Gruß Harry
www.H-Soft.info
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#4

Re: (Indy) TCPClient bekommt zuviel vom Server

  Alt 20. Apr 2006, 22:37
Deine Demo läuft bei mir in deutlich sichtbaren Schritten, aber warum? Meine TEST.DAT hat 466 KByte. Nach dem Studium der Dokumentation bin ich leicht irritiert. Die SendBufferSize ist 32 KByte per default. Deine Akrobatik mit 2048 ist relativ nutzlos, wenn ich der Online-Hilfe glauben darf. Wie hast du getestet? Protokolliere mal bei jedem ReadStream die Anzahl der empfangenen Bytes. Dateien mit maximal 32 KByte müssten in einem Rutsch übertragen werden. Ist dir bewusst, dass deine GETFILESIZE-Mimik das ohnehin schon verwendete Protokoll doppelt?

marabu
  Mit Zitat antworten Zitat
Benutzerbild von Harry M.
Harry M.

Registriert seit: 29. Okt 2004
Ort: Halle
462 Beiträge
 
#5

Re: (Indy) TCPClient bekommt zuviel vom Server

  Alt 21. Apr 2006, 04:30
Hey marabu,

Das Problem habe ich wiefolgt gelöst:

Server:
Delphi-Quellcode:
AThread.Connection.WriteLn(Trim (slFileList.Text) );
// Hier flog am Ende ein #13 mit durch was beim ersten Empfang des Steam-Buffers mit übertragen wurde. Deshalb war die File am Ende immer grösser.
Danke Deiner Mühen.
Harry
Gruß Harry
www.H-Soft.info
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:01 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