![]() |
Indy TCP Server - On Execute = 100% Prozessorlast
Hallo.
Ich schreibe an einer Client- Server Applikation. Dazu verwende ich die Indy TCP Komponente. (Indy 10 @ Delphi 7) Soweit funktioniert das Grundgerüst auch. Auf dem Client habe ich mir einen Thread erstellt, welcher eingehende Daten entgegen nimmt und in meiner Protokoll- Klasse verarbeitet. Nun habe ich nur das Problem, dass, sobald sich der erste Client mit dem Server verbindet, dieser 100% Prozessor- Last auslöst. Das Ereignis OnExecute wird ständig aufgerufen, obwohl die InputBufferSize = 0 ist. Ich vermute, OnExecute wird von einem Thread ausgelöst, der sofort wieder ins Resume läuft. Und damit diese Last erzeugt. Kann ich gegen dieses Zustand etwas tun? Komme ich an diesen Thread um ihn z.B. nicht gleich in ein neues Resume zu schicken? |
Re: Indy TCP Server - On Execute = 100% Prozessorlast
Ein bisschen Code wäre vielleicht hilfreich. Eigentlich sollte das OnExecute nicht ständig aufgerufen werden.
Notlösung wäre ein sleep(100) einzubauen um dem Prozess etwas luft zu verschaffen, aber normalerweise sollte es auch anders gehen... //edit: Ach du meinst das OnExecute Ereignis von deinem Thread. Jo das wird ständig aufgerufen. Da ist sleep(100) ganz sinnvoll...Ich dachte, du meinst das vom IdTCPServer. Grüße |
Re: Indy TCP Server - On Execute = 100% Prozessorlast
Ok. Hier mal das Test-Programm:
Delphi-Quellcode:
Sobald nun ein Client sich zu dem Server verbindet wird das OnConnect einmal ausgeführt (pro Client- Verbindung).
unit u_TestServer;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IdBaseComponent, IdComponent, IdTCPServer; type TfMainForm = class(TForm) TCP_Connection: TIdTCPServer; procedure FormShow(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure TCP_ConnectionConnect(AContext: TIdContext); procedure TCP_ConnectionExecute(AContext: TIdContext); private { Private-Deklarationen } public { Public-Deklarationen } end; var fMainForm: TfMainForm; implementation USES Client_Communication; {$R *.dfm} procedure TfMainForm.FormShow(Sender: TObject); begin TCP_Connection.Active:=true; end; procedure TfMainForm.FormClose(Sender: TObject; var Action: TCloseAction); begin TCP_Connection.Active:=false; end; procedure TfMainForm.TCP_ConnectionConnect(AContext: TIdContext); begin AContext.Data:=TClientComm.Create; end; procedure TfMainForm.TCP_ConnectionExecute(AContext: TIdContext); begin Handle_IncomingData(AContext); end; end. Aber ab der ersten Verbindung wir die letzte Prozedur (Execute) permanent ausgelöst, obwohl der Client keine Daten sendet. Wenn ich in der Funktion Handle_IncomingData auf die Connection.IOHandler.InputBuffer.Size teste ist diese 0, außer der Client sendet was. In dem Fall wird die Funktion zu Ende ausgeführt. Aber die Prozedur Execute vom TCP Server wird ständig aufgerufen obwohl KEINE Daten angekommen sind. Und eben dieses verursacht die Last. Der Client verhält sich normal. Erzeugt keine Prozessorlast, außer wenn er halt was sendet (kurzzeitig). |
Re: Indy TCP Server - On Execute = 100% Prozessorlast
D.h. hier wird irgendwo dein Thread gestartet, oder: Handle_IncomingData(AContext);
Warum benutzt du da einen Thread. Die prozedur TCP_ConnectionExecute(AContext: TIdContext); wird doch immer aufgerufen, wenn Daten ankommen. Wenn du deinen Thread startet, ist klar dass er immer weiterläuft, auch wenn grad mal keine Daten vom Server empfangen werden. Ein Thread ist ja grade dazu da, unabhängig vom Hauptprogramm zu laufen. Also insbesondere wird das OnExecute ständig aufgerufen, solange der Thread was activ steht. Schickst du denn Daten in Form von einem Stream? |
Re: Indy TCP Server - On Execute = 100% Prozessorlast
Nein. Handle_IncomingData ist kein Thread. Sondern eine Funktion. Die Klasse für AContext.Data und die Funktionen, die der Server bedienen können sollen, sind einfach nur in einer Unit zusammen gefasst. Also es wird da kein Thread abgespalten. Die Funktionen des Servers (áus AContext.Connection den angekommenen Stream auslesen und auswerten) könnten genauso gut im Execute der TCP Komponente stehen (wären nur viele viele Seiten zu kopieren).
Transferiert werden Record- Strukturen, welche in MemoryStreams gepackt sind. Es werden also kleine Memorystreams übertragen (meist so 128-512 Bit). |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:14 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-2025 by Thomas Breitkreuz