Einzelnen Beitrag anzeigen

Nils_13

Registriert seit: 15. Nov 2004
2.647 Beiträge
 
#1

Socket: Bild herunterladen

  Alt 18. Nov 2009, 21:22
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;
  Mit Zitat antworten Zitat