Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Indy-Test optimieren (https://www.delphipraxis.net/180134-indy-test-optimieren.html)

sx2008 25. Apr 2014 22:18

AW: Indy-Test optimieren
 
Zitat:

Zitat von mjustin (Beitrag 1256981)
anstatt für jeden einzelnen Integerwert eine Verbindung zu Server aufzubauen...

Das dürfte eine Verbesserung von 180-fach (!) bringen.
TCP-Verbindungsaufbau: 3 Pakete
TCP-Verbindungsaufbau: 2 Pakete
Das sind dann 300 * (5 + 1) = 1800 Pakete
Schickt man alles auf einen Rutsch sind das: 5 Pakete + ca. 5 Pakete für Nutzdaten = 10 Pakete
1800 / 10 = 180
Die ACK-Pakete habe ich nicht berücksichtigt, aber das dürfte wenig ändern

stahli 25. Apr 2014 23:00

AW: Indy-Test optimieren
 
Oh Mann, da hätte "man" ja auch mal selbst drauf kommen können. :oops:
Es ist ja nachvollziehbar, dass der Verbindungsaufbau immer etwas Zeit kostet.

Jetzt übertrage ich die 301 Werte einfach als String-Liste und lese sie en Block wieder aus.
Das funktioniert hier auf dem PC erst mal ohne sichtbare Verzögerung, auch bei mehreren Clients.

Delphi-Quellcode:
// Server:
  ..
  else if (cmd = '?ALL') then
  begin
    S := IntToStr(T);
    for Index := Low(A) to High(A) do
      S := S + #13#10 + IntToStr(A[Index]);
    SendText(AContext, S);
  end
  ..

// Client:
  ..
  procedure ReadText(FClient: TIdTCPClient; cmd: String; SL: TStringList);
  var
    MS: TMemoryStream;
    I: Int64;
  begin
    FClient.Connect;
    if FClient.Connected then
    begin
      MS := TMemoryStream.Create;
      try
        FClient.Socket.WriteLn(cmd);
        I := FClient.Socket.ReadInt64;
        FClient.Socket.ReadStream(MS, I, false);
        MS.Position := 0;
        SL.LoadFromStream(MS);
        // Result := Copy(SL.Text, 1, Length(SL.Text) - 2); // SL.Text; //
      finally
        MS.Free;
      end;
    end;
    FClient.Disconnect;
  end;
  ..
    ReadText(IdTCPClient1, '?ALL', SL);
    T := StrToInt(SL[0]);

    Index := 1;
    while Index < SL.Count do
    begin
      A[Index] := StrToInt(SL[Index]);
      Inc(Index);
    end;
  ..
Wenn ich später von 1Mio Datensätzen 300 abrufen will, dann werde ich einfach die 300 Id`s, RecNo o.ä. in einer Anfrageliste übergeben und die Ergebnisse dann vom Server aus anfügen und zurück schicken.
Insofern macht es schon Sinn, direkt mit Stringlists zu arbeiten.


Vielen Dank Euch allen für die Hilfe! (und für mjustin ein :cheers: extra)

Sir Rufo 25. Apr 2014 23:15

AW: Indy-Test optimieren
 
Solange man um die Besonderheiten der StringList weiß und die keine Stolperfallen darstellen, kann man die nehmen, wie jedes andere Konstrukt, was sich in einen Stream und wieder zurück wandeln lässt.
Delphi-Quellcode:
sl.Add('test' + sLineBreak + 'data' );
writeln( sl[0] ); // test#13#10data

sl.SaveToStream( sm );
sm.Position := 0;
sl.LoadFromStream( sm );

writeln( sl[0] ); // test

BUG 26. Apr 2014 13:31

AW: Indy-Test optimieren
 
Um es nochmal zu betonen:
TCP-Verbindungen schnell hintereinander auf und ab zu bauen ist fast immer eine schlechte Idee.
Wenn es mit auf- und abbauen übertreibt, kann es sogar passieren, das einem die Ports ausgehen (bei insgesamt wenigen "gleichzeitigen" Verbindungen).

Zitat:

Zitat von Union (Beitrag 1256961)
Man braucht die Pakete für die Clients nur durchnumerieren. Die dann zu implementierende Prüfungslogik ist trival.

Und wenn man festgestellt hat das ein Packet fehlt? Selective Repeat, go-back N oder halt nur Best-Effort-Delivery? Was bedeutet das auf Anwendungsebene?
Klar kann man ein Protokoll basierend auf UDP haargenau auf seine Anwendung zuschneiden, aber für allgemeine Aufgaben würde ich immer mit TCP beginnen.
Natürlich ordentlich weggekapselt hinter einer anwendungsspezifischen Schnittstelle.

stahli 28. Apr 2014 23:14

AW: Indy-Test optimieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe noch mal einen aktuellen Projektstand angehängt (nur die Quellen).
Wenn man im Client jetzt auf das Formular klickt wird im Server ein Sleep(10Sec) und danach die Drehanweisung ausgeführt.
Da der Client die "Datenabfrage" und die "Drehanweisung" aber jetzt in verschiedenen Threads verschickt bleibt der Client bis zum "Berechnungsergebnis" quasi am Leben (zeigt weiter aktuelle Daten an).
Ohne getrennte Threads im Client würde der Client natürlich hängen, solange der Server noch nichts zurück schickt - die 10 Sekunden eben.

(Ich nutze hier einen anonymen Thread. Mit älteren Delphi-Versionen müsste man das natürlich umstellen.)


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:16 Uhr.
Seite 2 von 2     12   

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