Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Stream von Client nach Server schicken (https://www.delphipraxis.net/126609-stream-von-client-nach-server-schicken.html)

Synollus 29. Dez 2008 14:01


Stream von Client nach Server schicken
 
Ich habe bei euch schon oft die Suche benutzt :mrgreen:, aber jetzt bin ich an einem Punkt angekommen, an dem ich eure Hilfe mal brauche. :shock:

Ich habe den ImageServer (über TCP) aus den Indy 9 Demos ein wenig gekürzt, damit ich den Part in mein Programm bauen kann.

Der Server:

Delphi-Quellcode:
procedure TfrmServer.ServerExecute(AThread: TIdPeerThread);
var
  Path: String;
  fStream: TFileStream;
  tBM: tBitmap;
begin
  Try
    If Copy(UpperCase(AThread.Connection.ReadLn), 1, 3) = 'SRN' then
      begin
        Path := ExtractFileDir(ParamStr(0)) + '\images\ScreenShot.BMP';
        tBM := TBitmap.Create;
        ScreenShot(0, 0, Screen.Width, Screen.Height, tBM);
        If FileExists(Path) then DeleteFile(Path);
        tBM.SaveToFile(Path);
        tBm.FreeImage;
        FreeAndNil(tBM);
        fStream := TFileStream.Create(Path, fmOpenRead + fmShareDenyNone);
        AThread.Connection.OpenWriteBuffer;
        AThread.Connection.WriteStream(fStream);
        AThread.Connection.CloseWriteBuffer;
        FreeAndNil(fStream);
        AThread.Connection.Disconnect;
      end;
  Except
    on E : Exception do
      ShowMessage(E.Message);
  end;
end;
Der Client:

Delphi-Quellcode:
procedure TfrmClient.btnServerScreenShotClick(Sender: TObject);
var
  ftmpStream: TFileStream;
  Path: String;
begin
  Try
    With Client do
      begin
        WriteLn('SRN');
        Path := ExtractFileDir(ParamStr(0)) + '\ServerScreen.bmp';
        If FileExists(Path) then DeleteFile(Path);
        ftmpStream := TFileStream.Create(Path, fmCreate);
        While connected do
          ReadStream(fTmpStream, -1, True);
        FreeAndNil(fTmpStream);
        Disconnect;
        imgMain.Picture.LoadFromFile(Path);
      end;
  Except
  end;
end;
Nun ist mir eine kleine Sache aufgefallen. In dem Beispiel schickt der Server einen Screenshot an den Clienten. Ich brauche es aber genau andersherum. Daher meine Frage: Kann ich das einfach umkehren ohne dass ich jedem Programm noch das Gegenstück reinpacken muss, sodass jede EXE Server und Client hat?

Da ich es nicht so mit Streams habe, hoffe ich, dass ihr mir helfen könnt. :)

[APPEND1]: Achja, zur Info: Ich verwende Indy 9.

Synollus 29. Dez 2008 16:11

Re: Stream von Client nach Server schicken
 
Ich habe das jetzt einfach mal umgedreht, sodass der Client einen Stream an den Server schickt. Ich denke noch nach wie vor, dass das so nicht gehen wird, aber ich habe es einfach mal versucht. :D

Das sieht jetzt so aus.

Der Server:

Delphi-Quellcode:
procedure TfrmServer.ServerExecute(AThread: TIdPeerThread);
var
  Path: String;
  fStream: TFileStream;
  tBM: tBitmap;
begin
  Try
    If AThread.Connection.ReadLn = 'SSS' then
      begin
        ShowMessage('Wird ausgeführt ...');
        Path := ExtractFileDir(ParamStr(0)) + 'screen2.bmp';
        If FileExists(Path) then DeleteFile(Path);
        fStream := TFileStream.Create(Path, fmCreate);
        AThread.Connection.ReadStream(fStream, -1, True);
        FreeAndNil(fStream);
        Image1.Picture.LoadFromFile(Path);
      end;
  Except
  end;
end;
Der Client:

Delphi-Quellcode:
procedure TfrmClient.btnServerScreenShotClick(Sender: TObject);
var
  fStream: TFileStream;
  Path: String;
begin
  Try
    With Client do
      begin
        WriteLn('SSS');
        Path := ExtractFileDir(ParamStr(0)) + '\screen.bmp';
        fStream := TFileStream.Create(Path, fmOpenRead + fmShareDenyNone);
        OpenWriteBuffer;
        WriteStream(fStream);
        CloseWriteBuffer;
        FreeAndNil(fStream);
      end;
  Except
  end;
end;
Ich erhalte die ShowMessage 'Wird ausgeführt ...', sprich die Verbindung zwischen Client und Server steht. Die Datei vom Clienten (screen.bmp) existiert, doch er überträgt nichts. Es kommt kein Stream an, somit wird auch keine Datei screen2.bmp erstellt und Image1 bleibt leer.

Habe ich nur irgendetwas falsch gemacht, oder kann ich wirklich nicht Server und Client tauschen?

Klaus01 29. Dez 2008 16:43

Re: Stream von Client nach Server schicken
 
Guten Abend,

ohne das jetzt getestet zu haben.
In der Netzwelt ist es üblich, dass ein Client eine Verbindung zum Server aufbaut.

Für Dein Problem wäre es dann notwendig auf beiden Seiten einen Client und Server laufen zu haben.

Grüße
Klaus

Synollus 29. Dez 2008 16:54

Re: Stream von Client nach Server schicken
 
Zitat:

Zitat von Klaus01
Guten Abend,

ohne das jetzt getestet zu haben.
In der Netzwelt ist es üblich, dass ein Client eine Verbindung zum Server aufbaut.

Für Dein Problem wäre es dann notwendig auf beiden Seiten einen Client und Server laufen zu haben.

Grüße
Klaus

Hallo,

danke erstmal für deine Antwort. Der Client baut doch die Verbindung auf, oder habe ich dich nicht richtig verstanden? Ich habe das Connect, etc. hier erstmal weggelassen. Die erste Möglichkeit funktioniert, die zweite leider nicht, d.h. am Verbindungsaufbau kann es nicht liegen, da ich da nichts verändert habe und außerdem das WriteLn ausgeführt wird und auch ankommt.

Natürlich könnten die beiden Programme einen Server und einen Clienten haben, aber bis jetzt ging das alles prima. Warum sollte ich jetzt unbedingt für die letzte Funktion alles nochmal erweitern?

Ich hoffe hier hat jemand noch eine gute Idee, sonst scheint mir wirklich nicht viel übrig zu bleiben, als noch einen Clienten und einen Server hinzu zu stopfen.

mjustin 30. Dez 2008 22:16

Re: Stream von Client nach Server schicken
 
Zitat:

Zitat von Synollus
Ich hoffe hier hat jemand noch eine gute Idee, sonst scheint mir wirklich nicht viel übrig zu bleiben, als noch einen Clienten und einen Server hinzu zu stopfen.

Müsste im Prinzip schon funktionieren (ich habe auch schon eine bidirektionale Verbindung mit Indy 10 geschrieben, in der der Client Daten vom Server empfängt - aller dings auch asynchron d.h. in einem Empfangs-Thread).

Idee: als erstes würde ich mal etwas zwischen except und end schreiben, denn so wie der Code jetzt aussieht werden alle Exceptions schlicht unbemerkt unter den Tisch fallen.

Synollus 31. Dez 2008 11:58

Re: Stream von Client nach Server schicken
 
Zitat:

Zitat von mjustin
Zitat:

Zitat von Synollus
Ich hoffe hier hat jemand noch eine gute Idee, sonst scheint mir wirklich nicht viel übrig zu bleiben, als noch einen Clienten und einen Server hinzu zu stopfen.

Müsste im Prinzip schon funktionieren (ich habe auch schon eine bidirektionale Verbindung mit Indy 10 geschrieben, in der der Client Daten vom Server empfängt - aller dings auch asynchron d.h. in einem Empfangs-Thread).

Idee: als erstes würde ich mal etwas zwischen except und end schreiben, denn so wie der Code jetzt aussieht werden alle Exceptions schlicht unbemerkt unter den Tisch fallen.

Er geht nicht ins Except, also er gibt keine Fehlermeldung aus, wenn ich sie unter Except abfrage. Aber ich habe einen anderen Fehler gefunden:

Delphi-Quellcode:
Path := ExtractFileDir(ParamStr(0)) + 'screen2.bmp';
Da ExtractFileDir keinen Backslash am Ende liefert, musste ich ihn selbst einfügen.

Delphi-Quellcode:
Path := ExtractFileDir(ParamStr(0)) + '\screen2.bmp';
Jetzt wird die Zieldatei erstellt mit 0 KB. Wenn ich die Größe des Streames übergebe und beim Server vorher schreibe: FileStream.Size := ... dann wird die Zieldatei genauso gross, aber nur mit Leerzeichen.

[APPEND1] Erstaunlicherweise geht es doch auf einmal. :D Es waren zwar nur 20 KB aber als ich es dann nochmal testete und nach 10 Minuten wiederkam, war auf einmal etwas in der Zieldatei drin. :D

Dann werde ich mal versuchen das Ganze auf TMemoryStream umzuschreiben (ohne idStreamVCL, da ich nur Indy 9 habe).


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:16 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz