Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Image senden - Bin kurz vorm verzweifeln (https://www.delphipraxis.net/48522-image-senden-bin-kurz-vorm-verzweifeln.html)

PhilippW 26. Jun 2005 19:30


Image senden - Bin kurz vorm verzweifeln
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo!

Ich versuche jetzt schon seit Tagen ein ganz normales Bitmap mit den Client/Server-Komponenten zu versenden.
Das Bild soll vom Server verschickt werden und am Client ankommen.
Was ich nicht so ganz verstehe ist, dass ich das ganze bereits erfolgreich realisiert habe, allerdings beides zusammen in einem Programm (Server und Client befinden sich auf ein und der selben Form und der Server sendet das Bild übers Netzwerk zum eigenen Programm zurück).
Nun hab ich das ganze getrennt in jeweils ein eigenes Programm gesteckt und bin davon ausgegangen, dass es jetzt auch funktioniert, aber das tut es leider nicht.
Ich bekomme immer eine Access violation aber ein Bild kommt nicht an...
Das Programm befindet sich in der Anlage...

Ich hoffe, ihr könnt mir helfen das Problem zu lösen!

Mit freundlichen Grüßen

Philipp

BenjaminH 26. Jun 2005 19:34

Re: Image senden - Bin kurz vorm verzweifeln
 
Hallo,
such hier im Forum mal nach den besonderheiten vpn Sockets, da erfährst du z.B. das:
Wenn du eine Nachricht mit einem Socket versendest, kannst du nicht davon ausgehen, dass die Nachricht auch in einem Stück wieder ankomt, es passiert häufig, dass sie zerlegt wird.
Also musst du dafür sorgen, dass die Datei beim CLient wieder zusammengesetzt wird.
Viele Grüße, Benjamin

Zacherl 26. Jun 2005 19:43

Re: Image senden - Bin kurz vorm verzweifeln
 
Hallo,
guck mal hier in der OpenSource spalte:
IMT - Chat (mit Source)
Das ist ein von mir programmierter Chat, der auch die Sockets benutzt, um Dateien (auch Bilder) zu verschicken. Diese Funktion ist ein TChatServer und TChatClient implementiert.

Florian

PhilippW 26. Jun 2005 19:47

Re: Image senden - Bin kurz vorm verzweifeln
 
Zitat:

Zitat von BenjaminH
Hallo,
such hier im Forum mal nach den besonderheiten vpn Sockets, da erfährst du z.B. das:
Wenn du eine Nachricht mit einem Socket versendest, kannst du nicht davon ausgehen, dass die Nachricht auch in einem Stück wieder ankomt, es passiert häufig, dass sie zerlegt wird.

Ich hab das Forum und Google schon rauf und runter durchsucht aber nichts passendes gefunden...

Zitat:

Zitat von BenjaminH
Also musst du dafür sorgen, dass die Datei beim CLient wieder zusammengesetzt wird.
Viele Grüße, Benjamin

Ich hab noch nicht so viel mit Streams senden und so gemacht...
Beim Senden von Strings kommt immer alles komplett an...
Kannst du mir erklären, wie man die Teile zuammenfügt? :oops:

PhilippW 26. Jun 2005 19:51

Re: Image senden - Bin kurz vorm verzweifeln
 
Zitat:

Zitat von Florian Bernd
Hallo,
Das ist ein von mir programmierter Chat, der auch die Sockets benutzt, um Dateien (auch Bilder) zu verschicken. Diese Funktion ist ein TChatServer und TChatClient implementiert.

Ich hab schon in einen anderen Programm, für welches ich auch die Bilder-senden Geschichte verwenden will, ne Menge mit TServerSocket und TClientSocket gearbeitet und das müsste ich dann umschreiben (ist nicht wenig)...
Aber die sind ja laut Beschreibung lediglich abgeleitet, das bedeutet doch dann, dass es auch mit den "normalen" Komponenten gehen müsste, oder?

Zacherl 26. Jun 2005 19:55

Re: Image senden - Bin kurz vorm verzweifeln
 
So, noch mal gesucht:

Das hier muss ins OnClientRead Ereigniss des TClientSockets:

Delphi-Quellcode:
Var
  a: array[0..4096] of byte;
  i: integer;
  s: string;
  fs: tfilestream;
begin
  If FDaten = false then
  begin
    s := Socket.ReceiveText;
    If Copy(s, 1, 5) = 'Daten' then
    begin
      Delete(s, 1, 5);
      try
        FSize := StrToInt(s);
        FDaten := true;
        FStream.Clear;
      except
       
      end;
    end;
  end
  else
  begin
    i := Socket.ReceiveBuf(a, 4096);
    FStream.Write(a, i);
    FPos2 := FPos2 + i;
    // hiermit prozent ermitteln: floattostr(Round((fpos2 / fsize)*100));
    If FPos2 >= FSize then
    begin
      FDaten := false;
      FStream.Position := 0;
      FPos2 := 0;
     
    end;
  end;
FDaten: boolean;
FSize: int64;
Fpos2: int64;
FStream: TMemoryStream;

als globale Veriablen definieren!

und das hier muss zum Senden benutzt werden:

Delphi-Quellcode:
procedure SendFileToClient(clientindex: integer; filename: string);
Var i: integer; Buf: Pointer;
begin
  fstream.LoadFromFile(filename);
  Buf := FStream.Memory;
  serversocket1.Socket.connections[clientindex].SendText('Daten'+inttostr(fstream.size));
  sleep(sleeptime+50);
  serversocket1.Socket.connections[clientindex].SendBuf(buf^, fstream.Size);
end;
ClientIndex gibt die Nummer des Clients an.

Florian

PS: Ja, es geht auch mit den normalen Komponenten.

PhilippW 26. Jun 2005 20:16

Re: Image senden - Bin kurz vorm verzweifeln
 
Es funktioniert leider immer noch nicht...
Ich hab das Programm so umgeschrieben, dass es den Stream nicht aus einer Datei, sondern aus dem Bild selber (wie in meinem Versuch) erhällt.
Als ich das ganze gestartet hab, kam auf der Client-Seite wieder diese Zugriffs-Verletzung und mir ist aufgefallen, dass der Stream nicht "Created" wurde. Das hab ich geändert und jetzt kommt ein "Stream Read Error"...
Das kann doch nicht so kompliziert sein, oder?

Zacherl 26. Jun 2005 20:44

Re: Image senden - Bin kurz vorm verzweifeln
 
Also: im OnCreate Ereigniss des Formulars:

Delphi-Quellcode:
  FStream := TMemoryStream.Create;
zum speichern des Bildes im Stream:

Delphi-Quellcode:
  FStream.Clear;
  Image.Picture.SaveToStream(FStream);
Zum auslesen des Bildes bei dieser Stelle:

Delphi-Quellcode:
  If FPos2 >= FSize then
    begin
      [b]Image1.Picture.LoadFromStream(FStream);[/b]
      FDaten := false;
      FStream.Position := 0;
      FPos2 := 0;
    end;
Müsste gehen!

Florian

PhilippW 26. Jun 2005 20:55

Re: Image senden - Bin kurz vorm verzweifeln
 
Jetzt kommt wieder die AccessViolation... :wall:
Ich krieg das irgendwie nicht auf die Reihe...
Kannst du mir ein komplettes Programm schicken, in welchem der Stream aus einem Image geladen und beim Client wieder in ein Image gepackt wird? :oops:

svenwel.de 26. Jun 2005 21:04

Re: Image senden - Bin kurz vorm verzweifeln
 
http://www.dcw-group.net/index.php?m..._dateitransfer

PhilippW 26. Jun 2005 21:11

Re: Image senden - Bin kurz vorm verzweifeln
 
Zitat:

Zitat von svenwel.de
http://www.dcw-group.net/index.php?menue=cod&site=tuts/coding/delphi_dateitransfer

Über die Seite bin ich auch schon gestolpert, aber da wird der Stream auch aus einer Datei geladen...
Ich hab es auch da nicht hinbekommen, dass der Stream von dem Image selbst kommt...
Zumal funktioniert mein Programm ja auch, wenn es sich in einer einzigen Datei befindet (aber was für einen Sinn macht das schon?).

PhilippW 28. Jun 2005 12:47

Re: Image senden - Bin kurz vorm verzweifeln
 
Ich hab mich mit dem Thema und dem oben genannten Link nochmal weiter beschäftigt und versucht, ein JPEG, welches sich in einem Image befindet, zu versenden (also kein gespeichertes).
Doch selbst das funktioniert nicht...

Hier der Quelltext:

Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
  jpg: TJPEGImage;
begin
  jpg:=TJPEGImage.Create;
  jpg.Assign(form1.Image2.Picture.Bitmap);
  jpg.SaveToStream(sM);
  sM.Position:=0;
  try
    ClientSocket1.Socket.SendText(IntToStr(sM.Size));
  finally
    jpg.Free;
  end;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  rL: Integer;
  jPic: TJPEGImage;
begin
  rL := Socket.ReceiveLength; // rL die Größe der empfangen Daten zuweisen
  If rL = 0 then Exit; // Es kann sein das nix ankommt, das wäre schlecht ;)
  If Rec then
  begin                                   // Wenn im Receive-Mode:
    Socket.ReceiveBuf(Pointer(Int64(rM.Memory) + rM.Position)^, rL);
    rM.Position := rM.Position + rL;      // Position setzen
    If rM.Position = rSize then           // Wenn Datei vollständig:
    begin
      rM.Position := 0;                   // Position auf Null setzen, WICHTIG!
      jPic := TJPEGImage.Create;          // JPEG-Bild erzeugen
      try
        jPic.LoadFromStream(rM);          // Bild vom Stream laden
        Image1.Picture.Assign(jPic);      // Bild in das Image1 laden
      finally
        jPic.Free;                        // JPEG-Bild wieder fregeben
      end;
      rM.Clear;                           // Stream leeren
      Label1.Caption := 'Übertragung fertig';
      Rec := False;                       // aus den Receive-Mode gehen
    end;
  end else begin
    rSize := StrToInt(Socket.ReceiveText); // rSize die Größe der Datei zuweißen
    rM.SetSize(rSize);                    // Speicher reservieren
    rM.Position := 0;                     // Position auf Null setzen
    Rec := True;                          // Auf Receive-Mode stellen
    Socket.SendText('ok');                // Bestätigung senden
  end;
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  If Socket.ReceiveText = 'ok' then Socket.SendBuf(sM.Memory^, sM.Size);
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:54 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