Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi BMP bzw. Stream Indy TCPServer an alle verbundenen Clients schicken (https://www.delphipraxis.net/205676-bmp-bzw-stream-indy-tcpserver-alle-verbundenen-clients-schicken.html)

Hobbycoder 5. Okt 2020 12:19

BMP bzw. Stream Indy TCPServer an alle verbundenen Clients schicken
 
Hi,

hat jemand ein gutes Beispiel, wie ich per Indy TCPServer ein Bitmap oder besser noch einen Stream an alle aktuell verbundenen Clients senden kann?
Ich finde zwar viele Beispiele, wie ich das vom Client an den Server sende, aber ich habe bisher noch nicht viel in die andere Richtung gefunden.

Der Client soll dabei nicht das letzte Bild abfragen, sondern solange er verbunden ist einfach unaufgefordert empfangen.
Oder sollte ich das anders herum machen, dass der Client alle x Sekunden ein evtl. vorhandenes neues Bitmap abfragt?

Schwedenbitter 5. Okt 2020 18:19

AW: BMP bzw. Stream Indy TCPServer an alle verbundenen Clients schicken
 
Ich melde mich als Interessent mit an :lol:

@Moderator: Kann man irgendwo aktivieren, dass man ein Thema mitlesen möchte?

TurboMagic 5. Okt 2020 19:28

AW: BMP bzw. Stream Indy TCPServer an alle verbundenen Clients schicken
 
Wenn du E-Mail Benachrichtigungen an hast, wirst du automatisch informiert.
Zum eigentlichen Problem: der Server Socket hat sicher irgendwo eine Liste der verbundenen Clients. Da könnte man in einer Schleife die BMP Datei der Reihe nach an alle schicken. Das wäre aber bandbreitentechnisch ineffizient.

Evtl. gibt es eine Multicast Möglichkeit? Alternativ UDP, da gehen im lokalen Netzwerk auch Broadcasts.

Schwedenbitter 5. Okt 2020 20:06

AW: BMP bzw. Stream Indy TCPServer an alle verbundenen Clients schicken
 
Danke für die Antwort :thumb:

Zitat:

Zitat von TurboMagic (Beitrag 1474920)
Wenn du E-Mail Benachrichtigungen an hast, wirst du automatisch informiert.

Jetzt ja, da ich geantwortet habe. Aber kann man auch mitlesen, ohne sich zu beteiligen? :gruebel:

Zitat:

Zitat von TurboMagic (Beitrag 1474920)
Zum eigentlichen Problem: der Server Socket hat sicher irgendwo eine Liste der verbundenen Clients. Da könnte man in einer Schleife die BMP Datei der Reihe nach an alle schicken. Das wäre aber bandbreitentechnisch ineffizient.

Evtl. gibt es eine Multicast Möglichkeit? Alternativ UDP, da gehen im lokalen Netzwerk auch Broadcasts.

Zumindest bei mir hängt ein VPN mit einem anderen Subnet dazwischen. Da funktioniert leider kein UDP.
Und ich hatte schon mal den UDP-Server der Indies am Wickel. Entweder lag es an diesem, am UDP selbst oder an mir; jedenfalls wurden oft Pakete "verschluckt" (mir fällt keine andere Formulierung ein).

Hobbycoder 6. Okt 2020 12:53

AW: BMP bzw. Stream Indy TCPServer an alle verbundenen Clients schicken
 
Das Senden von IdTCPServer habe ich erst mal so gemacht:
Delphi-Quellcode:
procedure TForm2.OnScreenShot(Sender: TObject; BMP: Vcl.Graphics.TBitmap);
var
  i: Integer;
  List: TIdContextList;
  Context: TIdContext;
  ms: TMemoryStream;
begin
  if idtcpsrvr1.Active then
  begin
    ms:=TMemoryStream.Create;
    try
      BMP.SaveToStream(ms);
      List:=idtcpsrvr1.Contexts.LockList;
      for I := 0 to List.Count-1 do
      begin
        Context:=TIdContext(List[i]);
        ms.Position:=0;
        Context.Connection.Socket.Write(ms, SizeOf(ms));
      end;
    finally
      ms.Free;
    end;
  end;
end;
Wo ich aber noch nicht weiß, wie ich das mit dem Datenempfang im IdTCPClient zu machen. Die Komponente besitzt ja keinen Trigger der mich über den Empfang benachrichtigt. Ich dachte mir ich packe das in einen Thread und frage laufend ab, ob Daten zum Empfang anliegen. Oder gibt es da eine bessere Möglichkeit?

Jumpy 6. Okt 2020 13:46

AW: BMP bzw. Stream Indy TCPServer an alle verbundenen Clients schicken
 
Hilft dir das vielleicht weiter:

https://stackoverflow.com/questions/...g-tidtcpclient

Im Endeffekt musst du dir mal ein Protokoll überlegen, wie Server und Client miteinander kommunizieren. Einfach nur die Bitmaps losschicken hilft ja nicht. Du müsstest etwas schicken das beinhaltet:
"Achtung hier kommt ein Bitmap als Payload"
"Bitmap/Payload ist beendet"
"Jetzt kommt eine Prüfsumme/Hash"
"Prüfsumme/Hash beendet"

Jetzt kann der Client gucken, ob vom Payload alles angekommen ist und das ggf. nochmal anfordern.

Hier vielleicht noch ein Tutorial dazu:
https://entwickler-ecke.de/topic_66706.html

hoika 6. Okt 2020 15:57

AW: BMP bzw. Stream Indy TCPServer an alle verbundenen Clients schicken
 
Hallo,
der Client-Programm kann doch auch gleichzeitig Server sein.

TurboMagic 6. Okt 2020 17:23

AW: BMP bzw. Stream Indy TCPServer an alle verbundenen Clients schicken
 
Muss es denn Indy sein? Nix dagegen, aber ICS (u.a. in GetIt) ist komplett event getrieben und asynchron.
Dein Client würde dort ein OnDataAvailable Event bekommen wenn die BMP reinkommt.

Harry Stahl 7. Okt 2020 15:27

AW: BMP bzw. Stream Indy TCPServer an alle verbundenen Clients schicken
 
Zitat:

Zitat von Hobbycoder (Beitrag 1474878)
Hi,

hat jemand ein gutes Beispiel, wie ich per Indy TCPServer ein Bitmap oder besser noch einen Stream an alle aktuell verbundenen Clients senden kann?
Ich finde zwar viele Beispiele, wie ich das vom Client an den Server sende, aber ich habe bisher noch nicht viel in die andere Richtung gefunden.

Der Client soll dabei nicht das letzte Bild abfragen, sondern solange er verbunden ist einfach unaufgefordert empfangen.
Oder sollte ich das anders herum machen, dass der Client alle x Sekunden ein evtl. vorhandenes neues Bitmap abfragt?

Ich habe mich bei meinem Programm (https://www.hastasoft.de/pcnetwork/index.html) letztlich für die zweite Lösung entschieden (also Abfrage in einem vom User angebbaren Zeitraum), da oft nicht eine Rückverbindung vom Server zum Client gegeben ist, z.B. wenn die Verbindung über das Internet geht und der Client hinter einem Router sitzt, dann ist die Organisation schon etwas komplexer, dass der Stream dann auch an den richtigen Rechner innerhalb des Netzwerkes geht (kann man machen, indem man eine Port-Weiterleitung im Router an den konkret angegebenen Netzwerk-Rechner einrichtet, aber das einem IT- unerfahrenen Anwender zu erklären, ist nicht ganz so einfach).

Der Client fragt halt in einem Extra-Thread im festgelegtem Abstand ab, ob es ein aktualisiertes Bild gibt, wenn ja, liefert der Server das direkt mit und der Thread aktualisiert dann die Anzeige (natürlich innerhalb eines Synchronize-Aufrufs).

Auf dem Server innerhalb des Execute Events des Indy TCP Servers mache ich das dann einfach so (hier mal nur den Fall, dass der ganze Bildschirm übertragen werden soll, später übertrage ich nur sich zwischenzeitlich ergebene Änderungen):
Delphi-Quellcode:
  {$Region 'Ganzen Bildschirminhalt übertragen'}
  if pos ('getpic', sMsg) <> 0 then begin
    MyStream := TmemoryStream.Create;
    Try
      GetAPic (MyStream);
      MyStream.position := 0;

      SetKryptedStream (MyStream); // Image verschlüsseln, Stream steht danach bereits Position Zero

      AThread.Connection.IOHandler.WriteLn(myStream.Size.ToString);
 
      AThread.Connection.IOHandler.WriteBufferOpen;
      AThread.Connection.IOHandler.Write(myStream);
      AThread.Connection.IOHandler.WriteBufferClose;
    finally
      FreeAndNil(MyStream);
    end;
    EXIT;
  end;
  {$Endregion}
Es wird also ein Stream erzeugt, das Bild geholt und in den Stream gespeichert. Dann wird zunächst die Größe des Streams (auch zur Kontrolle übermittelt) und dann der Stream selber gesendet.

Michael II 7. Okt 2020 15:58

AW: BMP bzw. Stream Indy TCPServer an alle verbundenen Clients schicken
 
Zitat:

Zitat von Harry Stahl (Beitrag 1475037)
Ich habe mich bei meinem Programm (https://www.hastasoft.de/pcnetwork/index.html) letztlich für die zweite Lösung entschieden (also Abfrage in einem vom User angebbaren Zeitraum), da oft nicht eine Rückverbindung vom Server zum Client gegeben ist,

Bei tcp hast du eine Verbindung, welche Datenaustausch in beide Richtungen erlaubt. Sobald und solang also der Client mit dem Server verbunden ist, hast du einfach zwei "Endpunkte", welche je Daten senden und empfangen können.

- D.h. der Client muss also nicht ständig fragen "Server hast du mir Daten". Der Server sendet einfach...
- Der Client muss keine Portweiterleitungen o.ä. im Router vornehmen.

https://de.wikipedia.org/wiki/Transm...ntrol_Protocol

Kurz: Der Client verbindet mit dem Server. Du lässt die Verbindung Client-Server offen. Sobald Client oder Server Daten senden wollen tun sie das einfach...


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:13 Uhr.
Seite 1 von 3  1 23      

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