![]() |
(Indy) TCPClient bekommt zuviel vom Server
Mahlzeit!
Ich möchte mit einem Indy TCPClient von einem Indy TCPServer eine Datei holen (was auch sonst :lol: ) 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 :pale: Der Client;
Delphi-Quellcode:
Der Server, welcher meiner Meinug nach läuft:
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;
Delphi-Quellcode:
Wo liegt der Fehler (ausser im Detail :lol: ) ?
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 = 'GETLIST' then begin if CreateFileList(ShreadFolder + '*.*', sFileName, slFileList) then slFileList.Text := StringReplace(slFileList.Text, '', '', [rfReplaceAll]); AThread.Connection.WriteLn(slFileList.Text); AThread.Connection.Disconnect; end; if sCommand = 'GETSIZE' then 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 = 'GETFILE' then 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; |
Re: (Indy) TCPClient bekommt zuviel vom Server
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 |
Re: (Indy) TCPClient bekommt zuviel vom Server
Liste der Anhänge anzeigen (Anzahl: 1)
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. |
Re: (Indy) TCPClient bekommt zuviel vom Server
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 |
Re: (Indy) TCPClient bekommt zuviel vom Server
Hey marabu,
Das Problem habe ich wiefolgt gelöst: Server:
Delphi-Quellcode:
Danke Deiner Mühen.
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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:59 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz