Delphi-PRAXiS

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...

mytbo 7. Okt 2020 17:00

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

Zitat von Hobbycoder (Beitrag 1474878)
hat jemand ein gutes Beispiel, wie ich per Indy TCPServer ein Bitmap oder besser noch einen Stream an alle aktuell verbundenen Clients senden kann?

Wenn es auch mit der Open Source Library mORMot sein darf, kannst du es mit WebSockets implementieren. In der Hilfe zum WebSockets support findest du die notwendigen Informationen. Das hilfreiche Forum findest du hier.

Bis bald...
Thomas

Harry Stahl 7. Okt 2020 19:36

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

Zitat von Michael II (Beitrag 1475039)
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...

Der Server kann direkt in die einmal erstellte Verbindung antworten, das stimmt. Aber wie bewerkstelligst Du es, wenn der Server von sich aus Daten an den Client senden will (etwa, nur wenn Bedarf besteht)? Denn es gibt ja kein vergleichbares "OnExecute" Event in der TCPidTCPClient Komponente...

Michael II 7. Okt 2020 21:31

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

meine Bemerkung zu tcp war genereller Art und nicht Indy/ICS oder was auch immer spezifisch.

Ich verwende ausschliesslich ICS und kenne Indy sehr schlecht (und die 4'700 seitige PDF Anleitung mag nun echt niemand lesen ;-)).

Aber soweit ich sehe, verwendet Indy "IOHandler" über welche die Kommunikation abgewickelt wird. Es gibt doch sicher Beispiele bei Emba.

Wenn du dort keins findest Hier gibt's eins inkl. herunterladbarem Code. Wenn du dem Serverprogramm noch ein SendeEdit:TEdit und einen SendeButton:TButton spendierst und das Beispiel durch den folgenden Code erweiterst

Delphi-Quellcode:
procedure TFServer.SendeButtonClick(Sender: TObject);
begin
  broadcastmessage( SendeEdit.Text );
end;
dann hast du ein "Client kann senden" und "Server darf aber auch" Beispiel.

Harry Stahl 7. Okt 2020 23:10

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

Zitat von Michael II (Beitrag 1475061)

Wenn du dort keins findest Hier gibt's eins inkl. herunterladbarem Code...

Wow, herzlichen Dank, wieder was dazugelernt...

Das wird mir bei einer Reihe von meinen Netzwerkprogrammen das Handling sehr vereinfachen...:thumb:

(Das ist ein schönes Beispiel hier, dass man auch mit Wissenszuwachs belohnt werden kann, wenn eigentlich selber weiterhelfen wollte...)

Nachtrag: Interessanterweise scheint es dann so zu sein, dass mit der idTCPClient-Componente nach einem Writeln nicht mehr direkt eine Antwort des Servers abgefragt werden kann, da die idThreadComponente offensichtlich die Nachrichten zuerst abfängt.

Meine bestehende Anwendung kann ich daher leider nicht so einfach umstellen (müsste Senden und Empfangen splitten), aber für neue Anwendungen sicher eine Option...

Schwedenbitter 8. Okt 2020 06:06

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

Zitat von Harry Stahl (Beitrag 1475065)
(Das ist ein schönes Beispiel hier, dass man auch mit Wissenszuwachs belohnt werden kann, wenn eigentlich selber weiterhelfen wollte...)

Und das ist auch der Grund, warum ich hier mitlesen wollte. So eine Funktion scheint es im Forum nicht zu geben: E-Mail Benachrichtigung zu einem Thema, wo man nichts schreibt :gruebel:

Aber mal zum Thema zurück:
Kümmern sich die Indys/ICS darum, dass die Pakete vollständig und in der richtigen Reihenfolge ankommen?
Ein Screenshot - noch dazu als BitMap - dürfte recht groß sein. Wenn man das z.B. mittels VPN über das Internet sendet, wird das bei einer MTU von 1.500 Bytes sonst echt spannend.

himitsu 8. Okt 2020 07:51

AW: BMP bzw. Stream Indy TCPServer an alle verbundenen Clients schicken
 
Um das Ankommen, die Reihenfolge und die Datenintegrität kümmert sich das Transport-Protokoll, also z.B. hier TCP/IP, nicht die Indy.
Die Packete sind nummeriert und werden bei Ankunft entsprechend behandelt.
Indy kümmert sich nur um die Übertragungsprotokolle (HTTP/FTP/...).

Bei UDP dagegen kann was verloren gehen, da nur "blind" gesendet wird, aber es keine Rückantwort gibt.

Michael II 8. Okt 2020 08:05

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

Zitat von Schwedenbitter (Beitrag 1475069)
Kümmern sich die Indys/ICS darum, dass die Pakete vollständig und in der richtigen Reihenfolge ankommen?
Ein Screenshot - noch dazu als BitMap - dürfte recht groß sein. Wenn man das z.B. mittels VPN über das Internet sendet, wird das bei einer MTU von 1.500 Bytes sonst echt spannend.

Wenn du eine tcp Verbindung aufbaust, dann musst du dich nicht um die Reihenfolge der Daten kümmern; auch nicht um MTU, das geschieht nicht in "deiner Schicht".
D.h. du kannst zum Beispiel 5*32KB und dann noch 3*12KB senden - und alles kommt (bei tcp) immer in der korrekten Reihenfolge an. Ein Paket kann in mehreren Teilen ankommen, oder es landen gleich mehrere Pakete aufs Mal bei deinem Programm. Je nach verwendeter Methode zum Einlesen der Daten (Indy/ICS) merkst du davon was (oder eben auch nix).

Wie weiter oben erwähnt wird: Wenn du über eine Verbindung zum Beispiel Chatmeldungen und Bitmaps senden willst, dann musst du für ein Protokoll sorgen, dank welchem du erkennst was ankommt.

Am besten definierst du einen "Meldungstyp" in der Art: WAS WIEVIEL DATEN
Wenn du eine Bitmap sendest, dann sendest du WAS=BITMAP WIEVIEL=LÄNGE DER DATEN DATEN=BITMAPDATEN. Wenn du eine Chatmeldung sendest, dann sendest du CHAT 5 HALLO.

Der Empfänger liest ankommende Daten in einen Buffer, und übergibt diesen Buffer einem Parser, welcher checkt, ob eine vollständige Meldung angekommen ist. Wenn eine Meldung angekommen ist, dann löschst du die Meldung aus dem Buffer und rufst entsprechende Hilfsfunktionen (Chatmeldung anzeigen, Bitmap speichern etc.) auf. Wenn der Buffer noch nicht leer ist, dann rufst du erneut den Parser auf, bis sämtliche Befehle abgearbeitet sind.

Schwedenbitter 8. Okt 2020 09:40

AW: BMP bzw. Stream Indy TCPServer an alle verbundenen Clients schicken
 
Ich stelle gerade fest, dass ich meine Frage wohl missverständlich formuliert habe. Entschuldigung!

Ich habe bereits ein Chat-Programm auf Basis der schon genannten Empfehlung, welches hier schon empfohlen wurde.
Zitat:

Zitat von Jumpy (Beitrag 1474967)

Zwangsläufig hatte ich mich mit den Untis beschäftigt. Und zumindest beim Bitmap-Empfang erfolgte eine Prüfung, ob die Pakete in der richtigen Reihenfolge kamen. Auch das System TCP/IP meine ich mit meinem laienhaften Verständnis einigermaßen erfasst zu haben. Ich bin eben nur Hobby-Programmierer.

Aber:
  1. Verstehe ich das richtig, dass ich das alle eben genannte vergessen kann und mich bei den Indys bloß noch um das Übertragungsprotokoll als solches kümmern muss? (Das dürfte für den Fragenersteller auch interessant sein.)
  2. Und verstehe ich das richtig, dass die Indys das auch so machen, dass mein Programm nicht mehr "einfriert", wenn die Verbindung eines Client hängt? (Bei Narses gibt es dazu einen händischen, aus meiner Sicht aufwändigen QoS-Teil in der Unit.) Oder wäre das nur bei den genannten ICS so?
:gruebel:

mjustin 8. Okt 2020 11:03

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

Zitat von Schwedenbitter (Beitrag 1475089)
  1. Verstehe ich das richtig, dass ich das alle eben genannte vergessen kann und mich bei den Indys bloß noch um das Übertragungsprotokoll als solches kümmern muss? (Das dürfte für den Fragenersteller auch interessant sein.)
  2. Und verstehe ich das richtig, dass die Indys das auch so machen, dass mein Programm nicht mehr "einfriert", wenn die Verbindung eines Client hängt? (Bei Narses gibt es dazu einen händischen, aus meiner Sicht aufwändigen QoS-Teil in der Unit.) Oder wäre das nur bei den genannten ICS so?

1. ja, genau so ist es (kein eigenes "Parsing" notwendig um zu erkennen ob eine auf Netzwerkebene päckchenweise gesendete Nachricht komplett angekommen ist)
2. serverseitig: ja; clientseitig muss ein Thread verwendet werden wenn die restliche Anwendung nicht einfrieren soll

stahli 8. Okt 2020 11:18

AW: BMP bzw. Stream Indy TCPServer an alle verbundenen Clients schicken
 
[OT]

Zitat:

Zitat von Schwedenbitter (Beitrag 1475069)
Und das ist auch der Grund, warum ich hier mitlesen wollte. So eine Funktion scheint es im Forum nicht zu geben: E-Mail Benachrichtigung zu einem Thema, wo man nichts schreibt :gruebel:

Doch, oben über Themen-Optionen kannst Du das Thema explizit abonieren.

[/OT]

mjustin 8. Okt 2020 11:24

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

Zitat von Harry Stahl (Beitrag 1475065)
Nachtrag: Interessanterweise scheint es dann so zu sein, dass mit der idTCPClient-Componente nach einem Writeln nicht mehr direkt eine Antwort des Servers abgefragt werden kann, da die idThreadComponente offensichtlich die Nachrichten zuerst abfängt.

Dann lege das WriteLn ebenfalls in den Thread (vor das ReadLn), dann hast du Request/Response Paare. Das Beispiel ist eher an Telnet angelehnt, wo Client und Server spontan (unabhängig voneinander) etwas mitteilen dürfen.

Michael II 8. Okt 2020 12:00

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

Zitat von mjustin (Beitrag 1475101)
Das Beispiel ist eher an Telnet angelehnt, wo Client und Server spontan (unabhängig voneinander) etwas mitteilen dürfen.

Zum Beispiel einander Chatmeldungen oder Bilder senden ;-). Oder bei Spielen, wenn du Daten austauschen willst.

Wenn du nur rasch "Hallo Server, gib mir was" senden willst, dann sind readln/writeln sicher ok - aber für komplexere Anwendungen bist du mit Indys IOHandler oder ICSOverbytes asynchronen Komponentan wesentlich flexibler unterwegs.

mjustin 8. Okt 2020 12:12

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

Zitat von Michael II (Beitrag 1475106)
Wenn du nur rasch "Hallo Server, gib mir was" senden willst, dann sind readln/writeln sicher ok - aber für komplexere Anwendungen bist du mit Indys IOHandler oder ICSOverbytes asynchronen Komponentan wesentlich flexibler unterwegs.

Ich meinte ReadLn / WriteLn über Indy. Das kann auch bei Indy der IOHandler.

Michael II 8. Okt 2020 12:31

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

Zitat von mjustin (Beitrag 1475108)
Ich meinte ReadLn / WriteLn über Indy. Das kann auch bei Indy der IOHandler.

Wenn ich gecheckt hätte, dass wir dasselbe sagen, dann hätte ich nix geschrieben ;-).

mjustin 8. Okt 2020 20:25

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

Zitat von Hobbycoder (Beitrag 1474962)
Das Senden von IdTCPServer habe ich erst mal so gemacht:

Das ist soweit ok, wenn der Client nichts anderes macht als die Bitmaps zu empfangen. Es hat allerdings zwei Nachteile: es wird nur ein Bild gleichzeitig gesendet, wenn es mehrere Clients gibt, dann werden sie nicht parallel mit Daten beliefert, sondern einer nach dem anderen. Und dann ist OnExecute Methode tabu oder wird komplizierter: in OnExecute darf natürlich nicht in den Socket geschrieben werden, während das Bild übertragen wird.

Best practice ist daher, jeder Connection eine Queue zuzuordnen, in der über den Hauptthread Bilder hinzugefügt werden und die dann in OnExecute abgearbeitet wird. Die Clients werden dann parallel Daten erhalten, und die gesamte Steuerung der Kommunikation befindet sich in OnExecute.

Wie man bei Indy weitere Attribute (wie z.B. eine Queue, oder Benutzernamen...) an die eingehenden Connections 'antackert' poste ich später. Es gibt einige Posts bei Stackoverflow in denen das beschrieben wird.

Hobbycoder 12. Okt 2020 10:25

AW: BMP bzw. Stream Indy TCPServer an alle verbundenen Clients schicken
 
Ich habe mittlerweile etwas lauffähiges zusammenbekommen.
Da ich mit Indey mittlerweise etwas besser kenne, bin ich dabei geblieben. ICS werde ich mir mal anschauen, aber da müsste ich mich neu einarbeiten. (Sind zwischen Indy und ICS performanceunterschiede bekannt? )

Ich habe das letztlich so gemacht, dass der Client halt beim Server sagt "Gib mir was" und der Server sendet halt per stream das Bild (zum verringern der Datenmenge als JPG) an den Client unmittelbar zurück.
So weit, so gut.
Vorerst habe ich damit das erreicht was ich wollte. Denn in meinem Fall reicht es aus in einem Interval von 10 Sekunden ein aktuelles Bild zu erhalten. Ich brauche keinen Livestream ala Teamviewer und ich muss auch nicht mit den anderen Bildschirm interagieren. Auch ist die interne Netzwerkstruktur hier nicht das Problem, denn ich habe selbst die Kontrolle über die Router/Firewalls dazwischen.

Aber natürlich packt einen bei einem solchen Projekt auch ein wenig der Ergeiz. Mittlerweise habe ich mir die Display Duplication API angeschaut, mit deren Hilfe es natürlich einfacher ist, die Datenmenge zu veringern, weil man nach dem ersten Bild nur noch die Teilbilder schickt, in denen sich Änderungen ergeben. Damit läßt sich auch bei geringerer Bandbreit ein gutes Ergebnis erzielen.

Harry Stahl 12. Okt 2020 14:48

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

Zitat von Hobbycoder (Beitrag 1475365)
Denn in meinem Fall reicht es aus in einem Interval von 10 Sekunden ein aktuelles Bild zu erhalten. Ich brauche keinen Livestream ala Teamviewer und ich muss auch nicht mit den anderen Bildschirm interagieren. Auch ist die interne Netzwerkstruktur hier nicht das Problem, denn ich habe selbst die Kontrolle über die Router/Firewalls dazwischen.

Aber natürlich packt einen bei einem solchen Projekt auch ein wenig der Ehrgeiz. Mittlerweise habe ich mir die Display Duplication API angeschaut, mit deren Hilfe es natürlich einfacher ist, die Datenmenge zu verringern, weil man nach dem ersten Bild nur noch die Teilbilder schickt, in denen sich Änderungen ergeben. Damit läßt sich auch bei geringerer Bandbreite ein gutes Ergebnis erzielen.

Nachdem ich diesen Thread las, hatte ich auch noch mal Lust bekommen, an meinem PC-Network Remote Server & Controller Programm weiter zu arbeiten. Das letzte mal war das vor ca. 5 Jahren. Mit aktuellen PC's, dem neuesten Delphi (das ja auch wirklich in den letzten Jahren für schnelleren Code sorgt) und kleineren Optimierungen habe ich das Programm noch mal deutlich von der Geschwindigkeit optimieren können, innerhalb des lokalen Netzwerks ist die Bildschirmübertragung fast Echtzeit.

Habe daher eine neue Version veröffentlicht, bei Interesse ist ein kurzes Demo (ca. 1 Minute) bezüglich der Bildschirm-Übertragung hier zu sehen: https://youtu.be/vZmSHxN0d68?t=30

Dabei muss ich anmerken, dass der Client in einer virtuellen Windows-Maschine lief und ich gleichzeitig das Video aufgenommen habe. "In echt" geht es also noch etwas schneller.

Dabei hat sich heraus gestellt, dass die Indys gar nicht das Problem waren, sondern das Einfangen des aktuellen Bildschirms (auf dem älteren Entwicklungs-PC nicht unter 40 MS machbar, auf dem neuen müsste ich mal testen, muss aber deutlich schneller sein).

Für das Überprüfen, welche Bereiche im Screenshot geändert sind, brauche ich ca. 8 ms (auch alter Entwicklungs-PC).

Auch wenn das eigentlich schnell genug sein sollte, würde mich Dein Hinweis auf die Display Duplication API interessieren. Hast Du das tatsächlich mal getestet und wenn ja, dann gibt es schon eine Delphi Implementation dafür?


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