Registriert seit: 23. Jun 2004
Ort: Velbert (NRW)
108 Beiträge
Delphi 2006 Enterprise
|
Re: BDS2006 Download einer Datei vom Webserver mit TClientSo
31. Aug 2007, 10:03
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;
Erfahrung ist etwas, daß man erst bekommt, kurz nachdem man es dringend gebraucht hätte.
|
|
Zitat
|