![]() |
BDS2006 Download einer Datei vom Webserver mit TClientSocket
Hallo,
ich lade in meinem Programm mit TClientSocket eine EXE Datei von einem Webserver. Bei meinen Test unter Windows XP habe ich festgestellt, das vor den Dateidaten im ersten Block der Header (erster Block 268 Byte) vom Webserver mitgeschickt wird. Zitat:
befinden sich schon im ersten Block(4004 Byte) Teile der Datei. Im ersten Fall unter XP endet der Header mit 2 x CRLF und dann kommen die Daten, im zweiten Fall stehen 3 x CRLF vor den Daten. Hat jemand eine Idee, wie man Header und Daten sicher trennt und wie sich z.B. ein Apache Webserver als Gegenstelle verhält ? Thanks in advance |
Re: BDS2006 Download einer Datei vom Webserver mit TClientSo
Warum verwendest du keine HTTP-Kompos?
|
Re: BDS2006 Download einer Datei vom Webserver mit TClientSo
Habe bei Tests mit den unterschiedlichsten Indy Version unter D5 etliche Hänger, kurioses Verhalten und wenig Abwärtskompatibilität zu älteren Versionen festgestellt und daher wenig Vertrauen dazu.
Im Prinzip klappt es ja auch mit der einfachen SocketVersion, wenn man herausfinden könnte, wie die Trennung Header/Daten funktioniert. Wenn es gar nicht anders geht, muß ich halt den Header nach der Längenangabe parsen, alle Blöcke speichern und am Ende den Header (EmpfangeneDatenMenge - Headerlängenangabe) vom Anfang der Daten löschen. |
Re: BDS2006 Download einer Datei vom Webserver mit TClientSo
1. Du kannst nicht einfach einen Block weglassen weil OnClientRead die Aufrufe teilt. Du kannst dich nicht darauf verlassen - OnClientRead kann beim nächsten Rechner für jedes Zeichen einzelnd aufgerufen werden (übertrieben, aber im Bereich des möglichen) und von daher musst du selber auf die Trennung achten.
2. Wenn keine Indys, dann nutze Windows: InternetOpenURL, InternetDownloadURL, etc. |
Re: BDS2006 Download einer Datei vom Webserver mit TClientSo
OK probiere ich mal aus, InternetOpenUrl habe ich ja gefunden aber ? InternetDownloadURL ?
Gehe ich richtig in der Annahme, daß für die o.g. Funktionen aber auch ein Internetexplorer installiert sein muß und ClientSocket auch ohne IE funktioniert ? |
Re: BDS2006 Download einer Datei vom Webserver mit TClientSo
Ja, aber der IE ist doch standardmässig installiert.
Wenn dich das stört, dann geht die Empfehlung wieder in Richtung Indys... |
Re: BDS2006 Download einer Datei vom Webserver mit TClientSo
Muß er aber nicht bleiben
![]() |
Re: BDS2006 Download einer Datei vom Webserver mit TClientSo
Zur Info, ich habe es jetzt durch Parsen und Auswertung der Content-Length gelöst.
Alle bisherigen Tests auf unterschiedlichen PCs und unter W2K Pro/Server und WXP funktionierten ohne Probleme. Nachfolgend die Testversion der Procedure.
Delphi-Quellcode:
procedure TForm1.DownloadFile(RemoteHost, RemoteFileName, LocalFileName: string; ClientSocket: TClientSocket);
var ReturnCode, Header, LenPos, FileSize, ReadSize : Integer; s, tmpStr, LocalFileTemp : string; szBuffer : array[0..4095] of Char; FileIn : TFileStream; FileOut : TFileStream; FileTmp : TFileStream; begin Form1.tag := 0; Memo1.Clear; Memo2.Clear; Memo3.Clear; try with ClientSocket do begin Host := RemoteHost; ClientType := ctBlocking; Port := 80; try Open; if RemoteFileName[1] <> '/' then begin RemoteFileName := '/' + RemoteFileName; end; { Anfrage senden } s := 'GET ' + RemoteFileName + ' HTTP/1.0'#13#10 + 'Host: ' + Host + #13#10#13#10; ReturnCode := Socket.SendBuf(Pointer(s)^, Length(s)); if ReturnCode > 0 then begin { Antwort empfangen } header := 0; LocalFileTemp := changeFileExt(LocalFileName,'.TMP'); FileTmp := TFileStream.Create(LocalFileTemp, fmCreate); try while (ReturnCode > 0) do begin FillChar(szBuffer, SizeOf(szBuffer), 0); ReturnCode := Socket.ReceiveBuf(szBuffer, SizeOf(szBuffer)); Memo1.Lines.Add(intToStr(ReturnCode)); // Info Blockgrösse if ReturnCode > 0 then begin if Header = 0 then begin Header := 1; Memo2.lines.Add(szBuffer); // Info 1. Block Memo3.lines.Add(szBuffer); // Info Daten FileTmp.Write(szBuffer, ReturnCode); ReadSize := ReadSize + ReturnCode; end else begin Memo3.lines.Add(szBuffer); // Info Daten FileTmp.Write(szBuffer, ReturnCode); ReadSize := ReadSize + ReturnCode; end; end; end; finally FileTmp.Free; end; // Header entfernen LenPos := AnsiPos('Content-Length:',Memo2.Text); if LenPos > 0 then begin tmpStr := trim(copy(Memo3.Text,LenPos,40)); // Eigene Funktion die einen String/Wert zwischen zwei Trennstrings liefert tmpStr := trim(ExtStrT2First('Content-Length:',chr($0D)+chr($0A),tmpStr)); try FileSize := StrToInt(tmpStr); FileIn := TFileStream.Create(LocalFileTemp, fmOpenRead); try FileIn.Seek(ReadSize - FileSize, soFromBeginning); ReturnCode := FileIn.Read(szBuffer,4096); FileOut := TFileStream.Create(LocalFileName, fmCreate); try while ReturnCode > 0 do begin FileOut.Write(szBuffer,ReturnCode); ReturnCode := FileIn.Read(szBuffer,4096); end; finally FileOut.Free; end; finally FileIn.Free; end; except Form1.tag := 2003; // Fehler FileSize Auswertung end; DeleteFile(LocalFileTemp); end; end else begin Form1.tag := 2002; Form1.caption := 'Keine Antwort von Server : ' + RemoteHost; end; Close; except Form1.tag := 2001; Form1.caption := 'Keine Verbindung zum Server : ' + RemoteHost; end; end; finally If Form1.Tag < 2000 then Form1.caption := '[' + tmpStr + ']'; // Länge end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:27 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