Entwickler-Ecke

Internet / Netzwerk - TBitMap über Socket senden?


jjturbo - Di 23.05.06 10:45
Titel: TBitMap über Socket senden?
Moin Forum,

ich möchte gerne ein BitMap über eine Socketverbindung senden.
Mein Testprogramm sieht folgendermassen aus:


Variablendeklaration

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
type TMyRec=Record
      Name       :String[55];
      Vorname    :String[55];
      HausNr     :Integer;
      Male       :Boolean;
      TelefonNr  :Integer;
      Ort        :String[55];
      From       :String[50];
      FromAdress :String[15];
      Gesendet   :TDateTime;
      Empfangen  :TDateTime;
      myBitMap   :TBitMap;
     end;

var MyRec : TMyRec;




Sendender PC

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
  with MyRec do begin
    Name         := 'Müller';
    Vorname      := 'Elfriede';
    HausNr       := 13;
    Male         := false;
    TelefonNr    := 999888555;
    Ort          := 'Irgendwo';
    Gesendet     := Now;
    Empfangen    := StrToTime('00:00:00');
    myBitMap     := Image1.Picture.Bitmap;//Dort ist irgendein Bild geladen
  end;

  for i := 0 to ServerSocket1.Socket.ActiveConnections-1
   do ServerSocket1.Socket.Connections[i].SendBuf(MyRec,SizeOf(MyRec));



Empfangender PC

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
begin
  Socket.ReceiveBuf(MyRec,SizeOf(MyRec));
  Image1.Picture.Bitmap := MyRec.myBitMap;//Zugriffsverletzung

end;


Die Daten werden empfangen, können auch alle richtig ausgewertet werden, nur das BitMap läßt sich nicht verwenden, sobald ich versuche dieses in mein Image zu laden, bekomme ich eine Zugriffsverletzung?
Weiß jemand Rat?

Dank Euch,

Gruß jjturbo


Narses - Di 23.05.06 10:57

Moin!

Du kannst keine dynamischen Objekte in einem Record versenden, die Variable vom Typ TBitmap ist doch nur ein Zeiger auf Daten, die auf dem Heap liegen... :roll: ist immer das gleiche mit dem Senden von Records... ;)

Du musst die Bilddaten selbst senden, da kommst du mit .Scanlines[] des Bitmap-Objekts ran. Um mit der Datenübertragung keine Probleme zu bekommen (ich kann nur dringend davon abraten, records zu versenden!), brauchst du ein Suche in: Delphi-Forum, Delphi-Library PROTOKOLL, und hier [http://www.delphi-library.de/topic_ProtokollChatTutorial+TServerClientSocket++V201_54269.html] kannst du mehr darüber erfahren. ;)

cu
Narses


jjturbo - Di 23.05.06 11:01

Ok, das mit dem BitMap leuchtet mir ein... :oops:

Aber wieso keine Records versenden?


Delete - Di 23.05.06 11:02

Moin,

hier ist ein Beispiel, wie man BMPs übers Netzwerk verschickt:
http://delphi.about.com/od/internetintranet/l/aa012004a.htm

Gruß rd3


Narses - Di 23.05.06 11:25

Moin!

user profile iconjjturbo hat folgendes geschrieben:
Aber wieso keine Records versenden?

Die ausführliche Erklärung findest du zum einen im Tut, zum anderen hast du den Hauptgrund doch schon selbst "entdeckt": dynamische Objekte (lange Strings, etc.). ;)

Weiterhin, dein Code ist potentiell defekt:

Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
begin
  Socket.ReceiveBuf(MyRec,SizeOf(MyRec));
  Image1.Picture.Bitmap := MyRec.myBitMap;//Zugriffsverletzung (klar, darum geht´s jetzt aber nicht)
end;

Was ist denn, wenn nicht das ganze Record eingetroffen ist? Du wertest nämlich nicht das Funktionsergebnis von ReceiveBuf aus, was die tatsächlich gelesene Anzahl Bytes liefert - und wer sagt, dass das SizeOf(MyRec) ist? :shock:

cu
Narses


jjturbo - Di 23.05.06 11:31

Ok ok, werde mir jetzt mal das Tut reinziehen :)


Vielen Dank erst mal für Eure Antworten.

Gruß, jjturbo


Narses - Mi 31.05.06 01:23

Moin!

Ich habe mal die ganze Problematik zu einem FAQ-Eintrag [http://www.delphi-forum.de/viewtopic.php?p=364011#364011] eingedampft. ;) Kommt doch einfach immer noch zu oft vor, diese Frage...

cu
Narses


jjturbo - Mi 31.05.06 06:24

Ich habe mir mittlerweile mal das Tutorial einverleibt, ich kann nur jedem, der noch nichts mit diesem Thema zu tun hatte, dringend empfehlen das mal durchzuarbeiten, lohnt sich wirklich!!!

Danke an Narses für dieses tolle Tutorial!!!

Gruß, jjturbo


Narses - Do 29.06.06 10:08

Moin!

Im Terminatorzeichen-Protokoll-Tutorial Teil 2 [http://www.delphi-library.de/topic_TerminatorzeichenProtokollTutorial++2+Sockets+v100_65487.html] wird eine Möglichkeit vorgestellt, wie man ein Bild (TBitmap) übertragen kann - also genau das, was hier die Problemstellung ist. ;)

Ich möchte aber noch darauf hinweisen, dass es sich um eine Übergangslösung handelt. Die "größe Lösung", das Binär-Protokoll-Tutorial, dauert leider noch ein bischen (ist wirklich viel Stoff... :?).

cu
Narses


Narses - Fr 13.10.06 15:17

Moin!

Hinweis: Mein voriger Beitrag bezog sich auf eine ältere Version des Tutorials. Das Tutorial liegt mittlerweile in einer neuen, deutlich verbesserten Version vor, so dass jemand, der auf der alten Version aufgesetzt hatte, eventuell einen Blick auf die neue Version werfen möchte. ;)

cu
Narses