Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Indy IdTCPClient/IdTCPServer CPU Auslastung 100% (https://www.delphipraxis.net/147191-indy-idtcpclient-idtcpserver-cpu-auslastung-100-a.html)

AlBo55 3. Feb 2010 12:27


Indy IdTCPClient/IdTCPServer CPU Auslastung 100%
 
Hallo,
ich bin ratlos.
Ich probiere gerade mit den Indys
Der TCPClient soll auf Nachrichten vom Server warten. Klappt alles bestens. Aber sobald der Client connected ist habe ich eine CPU_Auslastung von 100%. Kann mir jemand da weiterhelfen?
Ich hab sowohl den Client als auch den Server völlig ausgehöhlt für die Anzeige hier:

Thread mit IdTCPClient
Delphi-Quellcode:
procedure BoTCPClient.Execute;
begin
  Client:=TIdTCPClient.Create(nil);
  Client.Host:=Host;
  Client.Port:=Port;
  i:=0;
  while not terminated do
  begin
    if not(Client.Connected) then
    begin
      try
        Client.Connect;
        // Anmeldestring senden       i:=0;
      except
        on E:Exception do
        begin
          Emsg:=E.Message;
        end;
      end;
    end;
    Sleep(15000);
  end;
  if Client.Connected then
  begin
    // Thread terminated
    Client.Disconnect;
  end;
//  Synchronize(VerbE);
//  PostMessage(hwd,SKY_CONNECT,0,0);
end;

Server
Delphi-Quellcode:
procedure TForm1.TCPServerExecute(AContext: TIdContext);
var
  I: Integer;
  st:integer;
begin
end;
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
// Server starten
begin
  TCPServer.Active:=true;
  lauf:=true;
  REdit.SelAttributes.Color:=clgreen;
  REdit.Lines.Add(DateTimeToStr(now)+': Server gestartet');
end;


Mir fällt nichts ein was da falsch sein könnte
Vielen Dank schon mal

Albrecht

AlBo55 4. Feb 2010 11:29

Re: Indy IdTCPClient/IdTCPServer CPU Auslastung 100%
 
Hallo,
sprecht zu mir
Ist die Frage so blödsinnig oder die Antwort so schwer?

Albrecht

DataCool 4. Feb 2010 11:46

Re: Indy IdTCPClient/IdTCPServer CPU Auslastung 100%
 
@Albo55:

Wäre recht hilfreich, wenn Du innerhalb Deines Thread-Execute
auch mal ein ReadLn auf die TCP-Connection machst.
Denn im Moment macht DEin Threads ausser verbinden, rein gar nichts
AUSSER: "Volle Kanne im Kreis zu Laufen", deshalb die 100% Last.

Nimm das Sleep raus, und setze den Intervall als ReadTimeOut beim Tcp-Client.

Hat rein gar nichts mit Indy zu tun,

Greetz Data

AlBo55 4. Feb 2010 12:21

Re: Indy IdTCPClient/IdTCPServer CPU Auslastung 100%
 
Vielen Dank für die Antwort

wie gesagt ich hab den code für die Anzeige hier ausgehöhlt
Das Original
Client
Delphi-Quellcode:
procedure BoTCPClient.Execute;
begin
  Client:=TIdTCPClient.Create(nil);
  Client.Host:=Host;
  Client.Port:=Port;
  Synchronize(GetHand);
  i:=0;
  while not terminated do
  begin
    if not(Client.Connected) then
    begin
      try
        Client.Connect;
        // Anmeldestring senden
        Synchronize(VerbA);
        Client.IOHandler.Write(Anmeld+#10);
        Synchronize(Anm);
        PostMessage(hwd,SKY_CONNECT,0,1);
        i:=0;
      except
        on E:Exception do
        begin
          Emsg:=E.Message;
          inc(i);
          Synchronize(Fehler);
          PostMessage(hwd,SKY_CONNECT,0,2);
        end;
      end;
    end;
    if Client.Connected then
    begin
      if cmd=1 then
      begin
        {Anmeldestring senden}
        Client.IOHandler.Write(Anmeld+#10);
        Synchronize(Anm);
        cmd:=0;
      end;
      if cmd=2 then
      begin
        {Bulk-Kommando senden}
        Client.IOHandler.Write('BULK'+DateTimeToStr(Date)+' 00:00:00-'+
         DateTimeToStr(Date+1)+' 23:59:59'+#10);
        Synchronize(Bu);
        cmd:=0;
      end;
      if cmd=3 then
      begin
        {beliebiges Kommando senden}
        Client.IOHandler.Write(command+#10);
        Synchronize(Bu);
        cmd:=0;
      end;
      while not Client.IOHandler.InputBufferIsEmpty do
      begin
        {es gibt noch was zu lesen}
        text:=Client.IOHandler.ReadLn;
        synchronize(UpdateMemo);
      end;
    end;
  end;
  if Client.Connected then
  begin
    // Thread terminated
    Client.Disconnect;
  end;
  Synchronize(VerbE);
  PostMessage(hwd,SKY_CONNECT,0,0);
end;
Server
Delphi-Quellcode:
procedure TForm1.TCPServerExecute(AContext: TIdContext);
var
  I: Integer;
  st:integer;
begin
  {Server Thread ausführen}
  text:=AContext.Connection.IOHandler.ReadLn;
  REdit.Lines.Add(DateTimeToStr(now)+': Nachricht: '
   +text);
  while lauf do
  begin
    case send of
     1: begin
          // Befehl senden
          AContext.Connection.IOHandler.Writeln(Edit2.Text);
          send:=0;
        end;
     2: begin
          // einzelnen Datensatz senden
          st:=-1;
          for I := 0 to sl.Count - 1 do
          begin
            if DFSuche(sl[i],'DatabaseId')=ListBox1.Items[ListBox1.ItemIndex] then
            begin
              st:=i;
              break;
            end;
          end;
          if st<>-1 then
           AContext.Connection.IOHandler.Writeln(sl[st]+#18);
          send:=0;
        end;
     3: begin
          // alle Datensätze senden
          for I := 0 to sl.Count - 1 do
          begin
            AContext.Connection.IOHandler.Writeln(sl[i]+#18);
          end;
          send:=0;
        end;
    end;
    if Copy(text,1,4)='BULK' then
    begin
      for I := 0 to sl.Count - 1 do
      begin
        AContext.Connection.IOHandler.Writeln(sl[i]+#18);
      end;
    end;
  end;
end;
die Auslastung verändert sich dabei leider überhaupt nicht


Albrecht

sirius 4. Feb 2010 12:41

Re: Indy IdTCPClient/IdTCPServer CPU Auslastung 100%
 
Wie gehst du (das Programm) vor?

Ist der Server und der Client im selben Programm?
Der Server ist im MainThread.
Der Client ist nicht im MainThread. (<-- Das mag Indy IMHO nicht)

Wann genau geht die CPU-Last hoch?
1. Du initialisierst den Server.
2. Du startest den Thread mit dem Client.
3. Erst (und genau dann) wenn der Client connected geht die CPU-Last hoch.
Ist das richtig?

DataCool 4. Feb 2010 12:43

Re: Indy IdTCPClient/IdTCPServer CPU Auslastung 100%
 
Hi,

auf den ersten Blick sieht der Client eigentlich OK aus,
es ist doch der Client-Process der die 100% Last hat oder ?
Den Ablauf des Threads schonmal Debuggt ?
Ich bin der Meinung Du solltest den isInputBufferEnpty nur in Kombination mit CheckDataSource(TimeOutIntervall) verwenden oder
einfach das ReadLn innerhalb eines Try except ausführen, wobei ein ReadTimeOut gesetzt sein muss und im Except FAll deine "Text" Variable auf "" zu setzen.

Welche Version der Indys hast Du ? 9 oder 10 ?

Greetz DAta

AlBo55 4. Feb 2010 13:16

Re: Indy IdTCPClient/IdTCPServer CPU Auslastung 100%
 
@ sirius:
Client und Server sind selbstständige Programme auf der gleichen VM

1. bis 3. korrekt.
Aber wenn der client disconnect schickt bleibt die Last oben
Erst Server.activ:=false senkt sie.

@ DataCool:
Indy 10
Readln mit try except werd ich einbauen

Server und client laufen einzeln bei ca. 1% Last
Es scheint also im Server zu liegen?

Albrecht

DataCool 4. Feb 2010 14:12

Re: Indy IdTCPClient/IdTCPServer CPU Auslastung 100%
 
@AlBo:

Wenn der Server auf 100% Last geht, wenn der Client sich abmeldet liegt es
daran das der Client sich nicht "sauber" abmeldet.
Der Indy-Server ist da etwas penibel, am besten der Client schickt ein "Quit" Signal und danach trennen
Server und Client beide die Verbindung.

Zusätzlich sollte im Server.OnExecute noch mit Check eingebaut werden:

Delphi-Quellcode:
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
begin
  // Prüfen ob Daten für die Verbindung vorhanden sind, dabei wird Status der Verbindung ebenfalls überprüft
  AContext.Connection.Socket.CheckForDataOnSource(500);
  // WEnn keine Daten vorhanden dann raus hier
  if AContext.Connection.Socket.InputBufferIsEmpty then exit;

  // Daten kommen jetzt wie gewohnt verarbeiten ...
end;
So bekommt der Server auch mit falls sich ein Client "unsauber" (z.B. WLAN Signal weg) abmeldet.
Trotzdem gehört so einem "sauberen" Protokoll ein "Quit" Signal.


[Edit]:

Wo wird den beim Server Deine Variable Lauf auf False gesetzt ?
OnExecute wird innerhalb eines Threads OnExecute ausgeführt und tritt immer wieder ein,
Da brauch/sollte eigentlich keine Schleife rein

Greetz Data

AlBo55 4. Feb 2010 16:55

Re: Indy IdTCPClient/IdTCPServer CPU Auslastung 100%
 
@ DataCool

lauf war so eine Verzweiflungstat um dem Fehler näher zu kommen.
das war aber nichts
ohne lauf sinkt sie Auslastung direkt nach dem Disconnect Danke.

das Protokoll kann ich leider nicht ändern, da mein Server nur eine Simulation ist.
meine eigentliche Arbeit ist der Client. der Originalserver steht aber für Testzwecke nicht zur Verfügung

Bleibt nur noch die 100% Last während des connect oder ist die etwa normal, da ja client und Server im "Lauschmodus" sein müssen?

Albrecht

DataCool 4. Feb 2010 19:31

Re: Indy IdTCPClient/IdTCPServer CPU Auslastung 100%
 
@Albo:

Die Last von 100% im Server wenn ein Client connected ist,
sollte auf keinen Fall so sein!
Ich habe bei meinen Server immer zwischen 100-200 Clients permanent connected --> CPU <= 2 %

Kannst Du bitte nochmal den Client-Thread und den Server.onExecute code posten,
dann schau ich mir das gerne nochmal an.
Wenn das nicht hilft schick mir(wenn Du darfst) den Source/oder Demo-Projekt via PM oder Mail.

Greetz Data


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