Hi,
ich möchte via Socket ein Bild herunterladen von einer Homepage. Es interessiert mich einfach wie so etwas funktioniert und wie man es mit Delphi umsetzen könnte. Ich habe einen alten Code auf meienr Platte gefunden. Er konnte früher mal einen Quelltext einer Seite herunterladen. Ich dachte mir, man könnte ihn auch problemlos für Grafiken verwenden, was jedoch leider nicht so geht.
Zum Code: Zunächst erstell ich mir eine simple Instanz der Klasse mit dem Host und dem "Link". Link ist vielleicht nicht ganz korrekt, aber das interessiert kaum, denn es handelt sich um alles hinter dem Host. Ich will einfach nur die Grafik
http://www.ndallmeyer.de/img/logo.jpg von meiner Seite herunterladen. Das Protokoll wird auf http in der Create gesetzt, daher fällt bei dem Parameter aHost des Konstruktors das http:// weg. Danach kommt der Pfad und der Dateiname (ohne führendes /, da dies die Klasse schon erledigt). Also hätten wir folgenden Erstellaufruf:
Create('www.ndallmeyer.de', 'img/logo.jpg');
Es werden in der Connect die Befehle ausgeführt:
Delphi-Quellcode:
GET /img/logo.jpg HTTP/1.1
Host: [
url]www.ndallmeyer.de[/
url]
Connection: close
<LEER>
<LEER>
Bei "Connection: close" frage ich mich, ob es nicht daran liegen könnte, aber mit einer Keep-Alive-Verbindung brachte es auch keine Grafik auf meine Platte. Ich bekomme nur das als Grafik:
Delphi-Quellcode:
HTTP/1.1 200 OK
Date: Wed, 18 Nov 2009 20:01:55 GMT
Server: Apache/2.2.10 (Linux/SUSE)
Last-Modified: Sun, 23 Aug 2009 09:05:27 GMT
ETag: "63059c-82da-471cb66fd03c0"
Accept-Ranges: bytes
Content-Length: 33498
Connection: close
Content-Type: image/jpeg
ÿØÿà
Das ist natürlich nicht mein Ziel, denn relevant sind nur die vier zerquetschten Zeichen. Aber zurück zum Code: Wenn der Client besteht, die Verbindung aufgebaut ist, werden über das Read-Ereignis Daten empfangen - der Debugger zeigt jedoch, dass Read nur einmal ausgeführt wird, danach wird nämlich die Verbindung über OnDisconnect geschlossen - das Bild wird zur Sicherheit (um weitere Fehler zu vermeiden) über eine StringList in die Textdatei gespeichert. (Das wird noch durch Streams abgelöst, da es mir besser gefällt, aber erstmal simpel StringList, lieber erst klein dann groß.)
Habt Ihr eine Idee, was ich falsch mache ? Vom Log her entspricht es sehr dem Firefox (dieser sendet noch ein paar Befehle mehr, welche ich auch schon durchprobiert habe, aber leider nichts änderten). Kann man eine Grafik auf diese Weise laden ? Ich dachte mir, wenn es der FF so macht, geht das, aber wer weiß.
Delphi-Quellcode:
type
// Client
TClientClass = class
constructor Create(aHost, aLink : String);
destructor Destroy; override;
private
Msgs : TRichEdit;
Link : String;
public
Client : TClientSocket;
Output : String;
procedure Connect(Sender: TObject; Socket: TCustomWinSocket);
procedure Disconnect(Sender: TObject; Socket: TCustomWinSocket);
procedure Read(Sender: TObject; Socket: TCustomWinSocket);
procedure Error(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
end;
constructor TClientClass.Create(aHost, aLink : String);
begin
Link := aLink;
Client := TClientSocket.Create(nil);
with Client do
begin
Host := aHost;
Service := 'http';
OnConnect := Connect;
OnDisconnect := Disconnect;
OnRead := Read;
OnError := Error;
Open;
end;
end;
destructor TClientClass.Destroy;
begin
if Client <> nil then
Client.Close;
end;
procedure TClientClass.Connect(Sender: TObject; Socket: TCustomWinSocket);
begin
with Socket do
begin
SendText('GET /'+Link+' HTTP/1.1' + #13#10);
SendText('Host: ' + Client.Host + #13#10);
SendText('Connection: close' + #13#10);
SendText(#13#10);
end;
end;
procedure TClientClass.Disconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
Bild(Output);
Client.Close;
end;
procedure TClientClass.Read(Sender: TObject; Socket: TCustomWinSocket);
begin
Output := Output+Socket.ReceiveText;
end;