![]() |
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 |
Re: Indy IdTCPClient/IdTCPServer CPU Auslastung 100%
Hallo,
sprecht zu mir Ist die Frage so blödsinnig oder die Antwort so schwer? Albrecht |
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 |
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:
Server
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;
Delphi-Quellcode:
die Auslastung verändert sich dabei leider überhaupt nicht
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; Albrecht |
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? |
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 |
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 |
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:
So bekommt der Server auch mit falls sich ein Client "unsauber" (z.B. WLAN Signal weg) abmeldet.
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; 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 |
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 |
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 22:32 Uhr. |
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 by Thomas Breitkreuz