Autor Beitrag
Softchaos67
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 103

XP Prof
Delphi 7
BeitragVerfasst: Do 20.01.05 09:48 
Hallo,
ich habe eine abgewandelte Client und Server Version des Indy Beispiel "ImageServer"
programmiert.
Von TIDTcpServer habe ich eine eigene Klasse abgeleitet, um spezielle Funktionen zu implementieren.
Nun das Problem: Beim Senden des Streams scheint alles OK zu sein.
Beim Client ist der Stream aber immer genau 33 Byte zu lange.
Woran könnte das liegen?

Der Server(Execute):
ausblenden volle Höhe 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:
var
    s, sCommand, sAction : string;
    memStream :TMemoryStream;
    tBM : tbitmap;
    jpg :TJPEGImage;
begin
   CS.Enter;
   try
       s := uppercase(AThread.Connection.ReadLn);
       sCommand := copy(s,1,3);
       sAction := copy(s,5,length(s));
       if sCommand = 'SRN' then begin
          // take snapshot
          lstRequests.add('Taking screen snap shot');
          tBM := TBitmap.Create;
          ScreenShot(0,0,Screen.Width,Screen.height,tBM);
          jpg := TJPEGImage.Create;
          jpg.Performance := jpBestQuality;
          jpg.CompressionQuality := 100;   // hier frei wählbare kompression (0-100)
          jpg.Assign(tBM);
          memStream := TMemoryStream.Create;
          jpg.SaveToStream(memStream);
          memStream.Position := 0;

          // open file stream to image requested

          // copy file stream to write stream
          AThread.Connection.OpenWriteBuffer;
          AThread.Connection.WriteStream(memStream);
          AThread.Connection.CloseWriteBuffer;

          AThread.Connection.Disconnect;
          // free the file stream
          FreeAndNil(memStream);

          tBm.FreeImage;
          FreeAndNil(tBM);
          FreeAndNil(jpg);

       end else if (sCommand <> 'MSG'and (sCommand <> 'LST'and (sCommand <> 'SRN'then begin
          lstRequests.add('ERR : Unknown command / action');
          AThread.Connection.WriteLn('ERR : Unknown command / action');
          AThread.Connection.Disconnect;
      end;
   except
//     on E : Exception do ShowMessage(E.Message);
   end;
   CS.Leave;
end;


und hier der Client:
ausblenden 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:
procedure TfrmLogVerw.Button2Click(Sender: TObject);
var
   MemoryStream : TMemoryStream;
begin
  inherited;
  try

     with MyTCPClient do begin
        if connected then Disconnect;
       Host := ColorStrGrd1.Cells[8,ColorStrGrd1.Row];
       Port := 6999;
       Connect;
       WriteLn('SRN:');
       MemoryStream := TMemoryStream.Create;
       while connected do ReadStream(MemoryStream,-1,true);
       Disconnect;
       MemoryStream.Position := 0;
       jpg := TJPEGImage.Create;
       jpg.LoadFromStream(MemoryStream); // Das geht schief weil der Stream 
                                         // 33 Byt zu lange
       Image1.Picture.Bitmap := JPEGtoBMP(jpg);
       FreeAndNil(MemoryStream);
       FreeAndNil(jpg);
    end;
   except
      on E : Exception do
          ShowMessage(E.Message);
   end;

Hat jemand ne Idee?
Danke
Gruss
Matthias
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Do 20.01.05 15:37 
Hallo,
mich stört ein bisschen der folgende Code:
ausblenden Delphi-Quelltext
1:
2:
       while connected do ReadStream(MemoryStream,-1,true);  
       Disconnect;
Dort weist du Delphi an, solange in den Stream zu lesen, bis das Kommando das solange liest wie eine Verbindung besteht, die Verbindung nicht trennst - mit anderen Worten, wenn du aus der Schleife rauskommst, besteht keine Verbindung mehr. Anschließend trennst du die Verbindung. Eigentlich muss da eine Exception auftreten. Vielleicht solltest du den Code ein wenig ändern:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
       MemoryStream.Size := 0;              // Man weiss ja nie....
       MemoryStream.Position := 0;          // ...was Delphi so intern macht ;)
       ReadStream(MemoryStream, -1, True);  // Jetzt wird alles gelesen, was die Verbindung hergibt
       // Ein Disconnect können wir uns sparen, da die Verbindung 100% nicht mehr existiert!


Gruß,
maxk

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Softchaos67 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 103

XP Prof
Delphi 7
BeitragVerfasst: Do 20.01.05 15:50 
Danke für den Hinweis.
Funzt auch aber selbe Fehlermeldung.
Wenn ich den Stream auf Position 33 setzte, dann kann ich den Stream lesen!
ausblenden Delphi-Quelltext
1:
2:
3:
       memStream.Position := 33;      //Stream ist 33 Byte zu lange
       jpg := TJPEGImage.Create;
       jpg.LoadFromStream(memStream);

Also wo kommen die 33 Byte am Beginn des Stream her??
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Do 20.01.05 16:05 
Keine Ahnung, guck doch mal, was drin steht:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
 // Buf ist ein String!
 SetLength(Buf,33);
 MemoryStream.Position:=0;
 MemoryStream.ReadBuffer(Buf[1],33);


Als Lösung folger Vorschlag: Deine 33 Bytes sind ein Überbleibsel von irgendeinem anderen Befehl, der vor dem Screenshot nicht verarbeitet wurde. Du solltest also mal prüfen, ob du im Server z.B. eine Greetingmeldung o.ä. eingestellt hast. Wenn du vor das WriteLn('SRN:') aber noch folgendes schreibst, sollte es eigentlich gehen (guck trotzdem woher der Fehler kommt!).
ausblenden Delphi-Quelltext
1:
2:
     if Socket.Readable(0then CurrentReadBuffer; // Falls es noch Zeichen gibt, hole sie ab
     WriteLn('SRN:'); // Request senden


maxk

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Softchaos67 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 103

XP Prof
Delphi 7
BeitragVerfasst: Do 20.01.05 16:22 
Im Buffer stand "Greetings from IServer...." :shock:
Das wars!
GreetingText... da muss man erstmal drauf kommen :wink:

mache jetzt ein Readln for dem Streamlesen und schon gehts...
Danke vielmals!
Gruss
Matthias
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Do 20.01.05 19:03 
Freut mich, dass es jetzt geht. Überlege aber, ob du den Greetingtext wirklich verwenden willst. Evtl. kannst du ihn dir auch einfach sparen (ich auch ganz gut für den Traffic).

maxk

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Softchaos67 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 103

XP Prof
Delphi 7
BeitragVerfasst: Fr 21.01.05 09:04 
Ja, ich weiss ja mit welchem Server ich mich vebrinde.
Der GreetinText fliegt raus.
Danke nochmals.
Gruss
Matthias