Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Image per Socket verschicken (https://www.delphipraxis.net/128372-image-per-socket-verschicken.html)

ermler1992 28. Jan 2009 19:30


Image per Socket verschicken
 
Hallo zusammen,
Ich habe einen ähnliches Thema schon einmal vor einem Jahr erstellt damals aber einfach nicht mehr weiter gewusst und dann das Interesse verloren. Jetzt muss ich für die Schule ein kleines Programm schreiben um darüber meine Facharbeit zu schreiben. Ich habe mir schon einige Beiträge dazu angeschaut aber irgendwie hab ich es nicht geschafft den geposteten Quellcode auf meine Bedürfnisse umzuschreiben. Es wäre ganz toll wenn mir jemand helfen könnte möglichst fix das Programm fertigzuschreiben damit ich mit der Facharbeit weiter machen kann.

Nun zu meiner Situation

Ich schreibe über die Problematik Bilder in Delphi 6 über Sockets zuverschicken. Leider habe ich von der Problematik sowie der Methode kaum Ahnung.

Das habe ich bisher

Client:
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    EdServerIP: TEdit;
    BtConnect: TButton;
    BtSend: TButton;
    LbStatus: TLabel;
    ImPicture: TImage;
    ClientSocket: TClientSocket;
    procedure BtConnectClick(Sender: TObject);
    procedure BtSendClick(Sender: TObject);
...
procedure TForm1.BtConnectClick(Sender: TObject);
begin
ClientSocket.host:=EdServerIP.Text;
ClientSocket.Active:=true;
LbStatus.Caption:='Connected';
end;

procedure TForm1.BtSendClick(Sender: TObject);
var stream:TMemorystream;
begin
Stream:=TMemoryStream.Create;
Impicture.Picture.SaveToStream(Stream);//funktioniert nicht Undefinierter Bezeichner "SaveToStream"
Stream.Position:=0;
ClientSocket.Socket.SendStream(Stream);
end;
Ersteinmal bekomme ich erst garkeinen Datenfluss hin, und zum zweiten weiß ich nicht wie das mit dem Protokoll funktionieren soll, also das der Server an den der Stream später gesendet wird weiß wann er die Daten für das Bild zusammen hat um es schließlich aus dem Stream zu lesen.

Ich hoffe ihr könnt mir helfen

Zacherl 28. Jan 2009 20:03

Re: Image per Socket verschicken
 
Erstmal:

Delphi-Quellcode:
Picture.Bitmap.SaveToStream()
Dann gibt es bei den Sockets die Möglichkeit Daten über das OnRead / OnClientRead Event zu empfangen. Dazu rufst du wenn die Events ausgelöst werden einfach:

Delphi-Quellcode:
Socket.ReceiveStream(), Socket.ReceiveText() oder Socket.ReceiveBuf()
auf.

Protokoll ist ja einfach:

C: Sendet Größe des Bildes
C: Sendet Bild
S: Empfängt Größe des Bildes
S: Empfängt das Bild in mehreren Blöcken, zählt die Datengröße und weiß somit wann das Bild komplett ist.

Gruß Zacherl

ermler1992 28. Jan 2009 20:53

Re: Image per Socket verschicken
 
Zuerst einmal danke für die schnelle Antwort.

Also wenn ich alles richtig verstanden habe dann sieht das ganze später so aus:

Client:

Delphi-Quellcode:
onread:
- Stream:=Memorystream.create;
- Impicture.Picture.Bitmap.SaveToStream(Stream);
- Stream.Position:=0;
- clientsocket.socket.sendtext(IntToStr(stream.size));
- clientsocket.socket.sendstream(Stream);

Server:
Delphi-Quellcode:
oncreate:
- Stream:=Memorystream.create;

onclientread:
- serversocket.socket.receivetext()//? Was soll jetzt in die Klammer rein? Eine Variable welcher die größe zugewiesen wird?
- serversocket.socket.receivestream(stream)//?Was gehört hier in die Klammer rein? Receivestream gibt es bei mir nicht, ich habe nur receiveLength(),receiveBuf() und receivetext()
- {server weiß wann der Stream komplett ist und dann }ImBild.picture.bitmap.loadfromstream(stream)
?!

Klaus01 28. Jan 2009 21:18

Re: Image per Socket verschicken
 
Delphi-Quellcode:
//- length:=sizeof(Stream)//? Ist "sizeof" richtig? Ich habe irgendwo gelesen das das immer gleich 4 ist.
- Stream.Position:=0;
- clientsocket.socket.sendtext(IntToStr(stream.size));
- clientsocket.socket.sendstream(Stream);
//- length:=0;
Grüße
Klaus

ermler1992 28. Jan 2009 21:28

Re: Image per Socket verschicken
 
Vielen Dank, dann ist der Punkt schon einmal geklärt, aber wie verarbeite ich die Daten jetzt Serverseitig?!

Klaus01 29. Jan 2009 07:28

Re: Image per Socket verschicken
 
Guten Morgen,

es könnte eventuell so gehen:

Delphi-Quellcode:

onclientread:
  BufSize: Integer;
  s: String;
  stream: TMemoryStream;
- serversocket.socket.receivetext(s)
- BufSize := StrToInt(s);
- Stream:=TMemorystream.create;
- stream.size:=BufSize;
- serversocket.socket.receiveBuf(stream,BufSize)//? 
- ImBild.picture.bitmap.loadfromstream(stream)
- stream.free;
Grüße
Klaus

Zacherl 29. Jan 2009 13:58

Re: Image per Socket verschicken
 
Das:
Delphi-Quellcode:
clientsocket.socket.sendtext(IntToStr(stream.size));
ist schonmal falsch. Es müsste viel mehr:

Delphi-Quellcode:
ClientSocket.Socket.SendBuf(Stream.Size, SizeOf(Stream.Size));
heißen.

ermler1992 29. Jan 2009 15:38

Re: Image per Socket verschicken
 
Ich glaube ich habe soweit alles verarbeitet.

Server:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
Stream:=TMemorystream.Create;
end;

procedure TForm1.ServerSocketClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var BufSize: Integer;
  s: String;
begin
Bufsize:=serversocket.Socket.receivelength;
stream.size:=bufsize;
serversocket.Socket.ReceiveBuf(stream,BufSize);
ImBild.picture.bitmap.loadfromstream(stream);
stream.free;
end;
der Server kann ohne Probleme kompiliert werden.

Client:
Delphi-Quellcode:
procedure TForm1.BtConnectClick(Sender: TObject);
begin
ClientSocket.host:=EdServerIP.Text;
ClientSocket.Active:=true;
LbStatus.Caption:='Connected';
end;

procedure TForm1.BtSendClick(Sender: TObject);
var stream:TMemorystream;
ssize:integer;
begin
Stream:=TMemoryStream.Create;
ssize:=stream.size;
Impicture.Picture.Bitmap.SaveToStream(Stream);
Stream.Position:=0;
ClientSocket.Socket.SendBuf(ssize, SizeOf(ssize));
clientsocket.socket.sendstream(Stream);
end;
Das Problem mit dem Konstantenobjekt habe ich jetzt gelöst und hier korrigiert. Habe stream.size in die Variable ssize geschrieben. Jetzt bekomme ich beim senden der daten folgende Fehlermeldungen:

http://87.106.244.110/daten/bilder/meldung2.bmp

und


http://87.106.244.110/daten/bilder/meldung1.bmp

fui-tak 11. Feb 2009 13:47

Re: Image per Socket verschicken
 
Ich weiß nicht ob das dein Problem lösen wird, aber wenn ich zweimal direkt hintereinander Daten versende, wie hier:
Zitat:

Zitat von ermler1992
Delphi-Quellcode:
...
procedure TForm1.BtSendClick(Sender: TObject);
...
ClientSocket.Socket.SendBuf(ssize, SizeOf(ssize));
clientsocket.socket.sendstream(Stream);
end;

funktioniert es meistens nicht so wie es soll. Ich würde die Daten in einer Übertragung versenden, nämlich in etwa so:

Delphi-Quellcode:
unit Unit1;

interface

uses
  ...

type
  TUebertragung = Record
        ssize: integer;
        stream: TMemorystream; //gibt das vielleicht irgendein Problem???
    end;
  TForm1 = class(TForm)

...


procedure TForm1.BtSendClick(Sender: TObject);
var uebertragung:TUebertragung;
begin
  Uebertragung.ssize:= Uebertragung.stream.size;
  Impicture.Picture.Bitmap.SaveToStream(Uebertragung.Stream);
  Uebertragung.Stream.Position:=0;
  ClientSocket.Socket.SendBuf(Uebertragung, SizeOf(Uebertragung));
end;
Das ist alles ungetestet und mit Streams hab ich noch nicht gearbeitet, aber vielleicht klappt's ja so


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