Entwickler-Ecke

Internet / Netzwerk - [SS,CS] Kleines Problem nach dem Empfang einer Bilddatei


ex4ct - Fr 21.07.06 14:12
Titel: [SS,CS] Kleines Problem nach dem Empfang einer Bilddatei
Habe ein kleines Problem nachdem ich eine Bilddatei von ServerSocket an ClientSocket schicke wird die empfangene Datei richtig im angegebenen Ordner gespeichert.
Wenn aber noch ClientSocket aktiviert ist kann man das Bild zwar öffnen aber man sieht kein Bild da es noch in Benutzung ist. Wie kann ich es machen dass wenn die Übertragung vollständig ist, die Datei nicht mehr in Benutzung ist ohne die Anwendungen zu schliessen oder ServerSocket und ClientSocket zu deaktivieren.


Born-to-Frag - Fr 21.07.06 14:51

Ich versteh das Problem nicht ganz.. ist es ein TFileStream? Dann mach doch einfach MyStream.Free?

Wenn nicht dann zeig mal bisschen mehr code ;)


greetz


ex4ct - Fr 21.07.06 14:54

Ja ist ein TFileStream..
Das mit MyStream.Free habe ich schon versucht aber damit wird die ganze anwendung bei mir geschlossen.. seltsam :D


Born-to-Frag - Fr 21.07.06 14:54

:shock:

Zeig mal ein bisschen Code


ex4ct - Fr 21.07.06 15:18

Client:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TForm1.Button1Click(Sender: TObject);
begin
 ClientSocket1.Socket.SendText('$SCREENSHOT$');

  FStream := TFileStream.Create('angekommen'+IntToStr(i)+'.jpg', fmCreate or fmShareDenyWrite);

  AUFPASSEN_FILEKOMMT:= TRUE;

end;


Jetzt reagiert ServerSocket auf SendText:'$SCREENSHOT$'...
Server:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
begin
if Socket.ReceiveText= '$SCREENSHOT$' then
FStream := TFileStream.Create(ExtractFilePath(ParamStr(0)) +'printscreen.jpg', fmOpenRead);
Socket.SendStream(FStream);
end;


Und anschliessend muss ClientSocket auf Socket.SendStream(FStream); reagieren...
Client:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
  iLen: Integer;
  Bfr: Pointer;
begin
  Try
  if AUFPASSEN_FILEKOMMT=True then begin
    iLen := Socket.ReceiveLength;
    GetMem(Bfr, iLen);
    try
      Socket.ReceiveBuf(Bfr^, iLen);
      FStream.Write(Bfr^, iLen);
      FreeMem(Bfr);
      finally
      FreeMem(Bfr);
    end;
  end;
  exceptend;
end;


So :D


Born-to-Frag - Fr 21.07.06 15:28

user profile iconex4ct hat folgendes geschrieben:
Client:

Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Button1Click(Sender: TObject);
begin
 ClientSocket1.Socket.SendText('$SCREENSHOT$');
end;


Jetzt reagiert ServerSocket auf SendText:'$SCREENSHOT$'...
Server:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  RecText: String;
begin
  RecText := Socket.ReceiveText;
  if RecText= '$SCREENSHOT$' then
  begin
    FStream := TFileStream.Create(ExtractFilePath(ParamStr(0)) +'printscreen.jpg', fmOpenRead);
    Socket.SendTextg('$READY$' + IntToStr(FStream.Size));
 
  end
  else if RecText = '$SEND$' then
    Socket.SendStream(FStream); //Alles ohne fehlerüberprüfung.. das schaffst du schon ;)
 
end;


Und anschliessend muss ClientSocket auf Socket.SendStream(FStream); reagieren...
Client:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
  iLen: Integer;
  Bfr: Pointer;
RecText: string;
begin
  if AUFPASSEN_FILEKOMMT then 
  try
    iLen := Socket.ReceiveLength;
    GetMem(Bfr, iLen);
    try
      Socket.ReceiveBuf(Bfr^, iLen);
      FStream.Write(Bfr^, iLen);
      FreeMem(Bfr);
    
      // blubb abfragen wie if fstream.size = receivesize then fertig_mit_download
    finally
      FreeMem(Bfr);
    end;

    Exit; 
  end;
  exceptend;

  RecText := Socket.ReceiveText;

  if Copy(RecText, 17) = '$READY$' then
  begin
    AUFPASSEN_FILEKOMMT := True;
    ReceiveSize := //Hier das hinter dem Read auswerten das kannst du selbst machen.. is ne globale variable
    Socket.SendText('$SEND$');
    FStream := TFileStream.Create('angekommen'+IntToStr(i)+'.jpg', fmCreate or fmShareDenyWrite);
  end;
end;


So :D



Also ich empfehle dir mal das Tutorial von Narses damit du ein gescheites Protokoll hast denn das ist nur provisorisch was ich da gemacht hab ;)

Du solltest wissen wann die Daten komplett empfangen wurden und dann FStream.Free machen und nicht im Timer wie dus mir in ICQ geschrieben hast ^^


greetz


EDIT: Hier der Link zum Tut: http://www.delphi-library.de/viewtopic.php?t=54269


ex4ct - Fr 21.07.06 18:11

Da krieg ich noch eine Fehlermeldung und bin mir sicher dass da noch andere Fehler sind.
Nach paar Stunden Arbeit sieht es so aus (Project habe ich unten angehängt):

Server:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, JPEG, StdCtrls, ScktComp, ExtCtrls;

type
  TForm1 = class(TForm)
    ServerSocket1: TServerSocket;
    procedure ServerSocket1ClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocket1ClientDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  FStream: TFileStream;

implementation

{$R *.dfm}

procedure ScreenCapture(Bmp: TBitmap);
var
  DeskWnd: HWnd;
  DeskDC: HDC;
  DeskCv: TCanvas;
  R: TRect;
  W, H: Integer;
begin
  if Bmp = nil then Exit;
  DeskWnd := GetDesktopWindow;
  DeskDC := GetWindowDC(DeskWnd);
  DeskCv := TCanvas.Create;
  DeskCv.Handle := DeskDC;
  W := Screen.Width;
  H := Screen.Height;
  R := Bounds(00, W, H);
  try
    Bmp.HandleType := bmDIB;
    Bmp.PixelFormat := pf24Bit;
    Bmp.Width := W;
    Bmp.Height := H;
    Bmp.Canvas.CopyMode := cmSrcCopy;
    Bmp.Canvas.CopyRect(R, DeskCv, R);
  finally
    DeskCv.Free;
    ReleaseDC(DeskWnd, DeskDC);
  end;
end;


procedure Bmp2Jpg(Bmp: TBitmap; Quality: Integer; sFileName: string);
type
  TJPEGQualityRange = 1..100;
var
  Jpg: TJpegImage;
begin
  jpg := TJpegImage.Create;
  try
    Jpg.CompressionQuality := Quality;
    Jpg.Assign(bmp);
    Jpg.SaveToFile(ChangeFileExt(sFileName, '.jpg'));
  finally
    jpg.Free;
  end;
end;

procedure Screenshot;
var
  bmp: TBitmap;
  sFileName:string;
begin
 sFileName := ExtractFilePath(ParamStr(0)) +'printscreen.jpg';
  bmp := TBitmap.Create;
  try
    ScreenCapture(Bmp);
    Bmp2Jpg(BMP, 100, sFileName);
  finally
    bmp.Free;
  end;
end;

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
Form1.Color:=clgreen;
end;

procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
Form1.Color:=clred;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var antwort:string;
begin
antwort:=Socket.ReceiveText;

if antwort= '$ScreenRequest$' then begin
Screenshot;
FStream := TFileStream.Create(ExtractFilePath(ParamStr(0)) +'printscreen.jpg', fmOpenRead);
Socket.SendText('$ScreenSize$' + IntToStr(FStream.Size));
end;

if antwort= '$SendeJetzt$' then begin
Socket.SendStream(FStream);
end;
end;

end.


Client:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    ClientSocket1: TClientSocket;
    Button1: TButton;
    Edit1: TEdit;
    procedure ClientSocket1Connect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
      ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure ClientSocket1Disconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  AUFPASSEN_FILEKOMMT:BooleaN;
  FStream: TFileStream;
  i:integer;
  bildgroesse:string;

implementation

{$R *.dfm}

function GetFileSize(const szFile: String): Int64;
var
  fFile: THandle;
  wfd: TWIN32FINDDATA;
begin
  result := 0;
  if not FileExists(szFile) then exit;
  fFile := FindFirstfile(pchar(szFile),wfd);
  if fFile = INVALID_HANDLE_VALUE then exit;
  result := (wfd.nFileSizeHigh*(MAXDWORD))+wfd.nFileSizeLow;
  windows.FindClose(fFile);
end;
procedure TForm1.ClientSocket1Connect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
Form1.Color:=clgreen;
end;

procedure TForm1.ClientSocket1Error(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
errorcode:=0;
ClientSocket1.Close;
ClientSocket1.Open;
end;

procedure TForm1.ClientSocket1Disconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
Form1.Color:=clred;
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
  iLen: Integer;
  Bfr: Pointer;
  antwort:string;
  antwort2:integer;
begin
antwort:=socket.ReceiveText;
antwort2:=Socket.ReceiveLength;

if Copy(antwort,0,12) = '$ScreenSize$' then begin
bildgroesse:=Copy(antwort,14,99999999999999);
Edit1.Text:=bildgroesse;
Socket.SendText('$SendeJetzt$');
AUFPASSEN_FILEKOMMT:=True;
end;

if AUFPASSEN_FILEKOMMT=True then begin
iLen := Socket.ReceiveLength;
GetMem(Bfr, iLen);
try
Socket.ReceiveBuf(Bfr^, iLen);
FStream.Write(Bfr^, iLen);
FreeMem(Bfr);
finally
FreeMem(Bfr);
end;
end;
//if fstream.size = StrToInt(bildgroesse) then fstream.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ClientSocket1.Socket.SendText('$ScreenRequest$');
FStream := TFileStream.Create('angekommen.jpg', fmCreate or fmShareDenyWrite);
end;

end.


Born-to-Frag - Fr 21.07.06 18:34

Mich würde mal interessieren wie du bei dem Copy() Befehl in Zeile 84 auf die Parameter 14 und 99999999999999 kommst?

Hast du dir Narses' Tut angesehen?


Narses - Fr 21.07.06 23:59

Moin!

@user profile iconex4ct: Du machst einen ziemlich grossen Fehler, wenn du dich auf die Ereignisse der Socket-Komponenten als Signalisierung verläßt. Hier [http://www.delphi-library.de/topic_Datenpakete+bei+den+SocketKomponenten+auseinanderhalten_56194.html] kannst du nachlesen, warum. ;)

cu
Narses


ex4ct - Sa 22.07.06 01:33

@ Born-To-Frag:
Stimmt die musste eigentlich eine 13 sein.

@ Narses:
Ich habe keine andere Wahl oder :)


Born-to-Frag - Sa 22.07.06 06:18

Doch hast du, du hast dir immernoch nicht sein Tutorial angesehen glaube ich :roll: