Delphi-PRAXiS
Seite 4 von 8   « Erste     234 56     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi schnelle Server Client Verbindung ohne Verluste (https://www.delphipraxis.net/216953-schnelle-server-client-verbindung-ohne-verluste.html)

TomyN 3. Apr 2025 10:45

AW: schnelle Server Client Verbindung ohne Verluste
 
Evtl. 32k Buffersize?

jaenicke 3. Apr 2025 10:48

AW: schnelle Server Client Verbindung ohne Verluste
 
Zitat:

Zitat von AJ_Oldendorf (Beitrag 1547776)
Durch das Sleep(1) funktioniert es auch (dass die CPU Auslastung nicht ansteigt), wenn kein Empfang mehr stattfindet.

Besser ist es, wenn du das Sleep nur ausführst, wenn keine Daten vorhanden waren. Dadurch verzögerst du den Empfang nicht, wenn Daten kommen.
Delphi-Quellcode:
procedure TMyTCPServer.OnExecuteHandler(AContext: TIdContext);
var
  Buffer: TIdBytes;
begin
  if AContext.Connection.IOHandler.InputBuffer.Size > 0 then
  begin
    while AContext.Connection.IOHandler.InputBuffer.Size > 0 do
    begin
      SetLength(Buffer, AContext.Connection.IOHandler.InputBuffer.Size); //<- so viel einlesen wie im Buffer enthalten ist
      AContext.Connection.IOHandler.ReadBytes(Buffer, Length(Buffer), False);
      FDataQueue.Enqueue(Buffer);
    end;
  end
  else
    Sleep(1);
end;
Zitat:

Zitat von AJ_Oldendorf (Beitrag 1547776)
Nur ist mir nicht klar, warum der Client 20 Telegramme á 61000 Byte abschickt und der Server 38 Stück empfängt wobei die meisten 32768 Byte lang sind und am Ende ein kürzeres. Warum nicht auch 20 Telegramme?

Darauf hast du keinen direkten Einfluss. Die Pakete werden für den Transport nach Bedarf unterteilt und beim Empfang in den Puffer geschrieben. Man kann dort zwar auch Einstellungen setzen, aber das garantiert dennoch nicht ein bestimmtes Verhalten.

AJ_Oldendorf 3. Apr 2025 11:12

AW: schnelle Server Client Verbindung ohne Verluste
 
@jaenicke: Danke für den Hinweis mit dem Sleep.
Beim Empfang muss ich sowieso die Telegramme wieder entsprechend zusammensetzen. Wollte es nur verstanden haben.

EDIT:
Das mit dem Sleep in deiner Variante funktioniert leider nicht. Da geht die CPU Auslastung auch auf 7% hoch nachdem der Empfang fertig ist

jaenicke 3. Apr 2025 18:23

AW: schnelle Server Client Verbindung ohne Verluste
 
Ach, Entschuldigung, das ist ja auch verkehrt herum. Ich habe es korrigiert. Die Beschreibung war korrekt, der Quelltext nicht. Das Sleep muss ins Else.

AJ_Oldendorf 4. Apr 2025 05:33

AW: schnelle Server Client Verbindung ohne Verluste
 
Ich danke dir :-)

AJ_Oldendorf 4. Apr 2025 11:14

AW: schnelle Server Client Verbindung ohne Verluste
 
@jaenicke:
Ich muss doch nochmal fragen, wie würde in deinem Beispiel denn die Implementierung aussehen, wenn der Client auch empfangen kann auf Telegramme vom Server? Da gibt es die
Delphi-Quellcode:
procedure OnExecuteHandler
ja nicht also müsste man zyklisch das pollen über einen Thread machen oder?

jaenicke 4. Apr 2025 19:49

AW: schnelle Server Client Verbindung ohne Verluste
 
Ja, das kannst du mit einem Thread machen, der pollt. Aber du musst dann auch sicherstellen, dass nicht gleichzeitig gelesen und geschrieben wird, sprich einen entsprechenden Lock verwenden.

Ich finde diese Architektur nicht schön, aber es funktioniert.

AJ_Oldendorf 7. Apr 2025 08:27

AW: schnelle Server Client Verbindung ohne Verluste
 
@jaenicke:

Hm, ein Thread, der zyklisch liest (wie in deinem Beispiel) und ein Thread, der zyklisch schreibt, geht nicht?
Ich muss die beiden untereinander wieder synchronisieren? Irgendwie habe ich erwartet, dass das die Indy intern machen :-(

jaenicke 7. Apr 2025 09:38

AW: schnelle Server Client Verbindung ohne Verluste
 
Du kannst z.B. das reine Senden und Empfangen mit TMonitor absichern:
Delphi-Quellcode:
TMonitor.Enter(AContext.Connection.IOHandler);
try
  AContext.Connection.IOHandler.ReadBytes...
finally
  TMonitor.Exit(AContext.Connection.IOHandler);
end;

AJ_Oldendorf 7. Apr 2025 11:13

AW: schnelle Server Client Verbindung ohne Verluste
 
Also beim Server, habe ich das Senden in einem Thread jetzt so ausgelagert:

Delphi-Quellcode:
var
  SendMsg : PAnsiString;
  Daten   : AnsiString;
  outMsg  : TIdBytes;

...
if ClientContext.Connection.Connected then
begin
  while (Sendeliste.Count > 0) do
  begin
    var sw4 := TStopwatch.StartNew;
    var t4 : Int64;

    SendMsg := Sendeliste.Items[0];
    Daten := SendMsg^;

    SetLength(outMsg, Length(Daten));
    Move(Daten[1], outMsg[0], Length(Daten));

    t4 := sw4.ElapsedMilliseconds; //Zeitmessung stoppen
    //Zeitmessung 01 auswerten

    sw4 := TStopwatch.StartNew; //Zeitmessung starten

    ClientContext.Connection.IOHandler.Write(outMsg);

    t4 := sw4.ElapsedMilliseconds; //Zeitmessung stoppen
    //Zeitmessung 02 auswerten

    sw4 := TStopwatch.StartNew; //Zeitmessung starten

    Dispose(SendMsg);
    Sendeliste.Delete(0);

    t4 := sw4.ElapsedMilliseconds; //Zeitmessung stoppen
    //Zeitmessung 03 auswerten
  end;
end
Zeitmessung 02 schlägt regelmäßig zu, 300ms ist normal (pro Aufruf), manchmal sogar länger.
Hast du eine Idee dazu?

Das ReadEvent habe ich über ein Merker geblockt, sodass in dem Moment kein Schreiben möglich ist. Da findet also in dem Moment nichts statt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:02 Uhr.
Seite 4 von 8   « Erste     234 56     Letzte »    

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