![]() |
Indy10 IdTCPServer Problem
Hallo zusammen,
ich habe ein Problem mit einem Indy IdTCPServer... Der Server läuft eine gewisse Zeit (ca 1 Std) ohne Probleme. Innerhalb dieser Zeit bekommt er alle 3 min einen Nachricht, die er an die verbunden Clients (derzeit 3) übermittelt. Nur dann plötzlich steigt er aus und ich verstehe nicht warum. Die Applikation bleibt zu sehen, jedoch ist ein beenden nur noch über den Taskmanager drin und eine neue Verbindung nimmt er auch nicht mehr an... Die Indy-Komponenten habe ich gestern erst geupdated um zu vermeiden, dass evtl. mit einem älteren Release zusammenhängt... Hier mal ein wenig Quellcode des Servers: Der Server wird zur Laufzeit erstellt:
Delphi-Quellcode:
Dann passiert im onExecute folgendes:
procedure TForm1.FormCreate(Sender: TObject);
begin IdTCPServer1 := TIdTCPServer.Create(self); IdTCPServer1.OnExecute := IdTCPServer1Execute; IdTCPServer1.OnConnect := IdTCPServer1Connect; IdTCPServer1.OnDisconnect := IdTCPServer1Disconnect; LoadSettings; IDTCPServer1.Active := true; if IDTCPServer1.Active then Log.Lines.Add(TimeToStr(now) + ': Server gestartet'); end;
Delphi-Quellcode:
OnConnect macht nur einen Eintrag in ein Memo (Log):
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var text, ip, command:string; i:Integer; List: TList; begin text := Acontext.Connection.IOHandler.ReadLn; ip := Acontext.Connection.Socket.Binding.PeerIP; Command:= Copy(text, 1, Pos(':', text)-1); if Command <> 'NOOP' then Log.Lines.Add(TimeToStr(now) + ': ' + ip + ' ' + text); if Command = 'TITLE' then title := text; if Command = 'HELO' then text := title; ListView1.Clear; List := IdTCPServer1.Contexts.LockList; for i := 0 to List.Count - 1 do begin TidContext(List.Items[i]).Connection.IOHandler.WriteLn(text); with Listview1.Items.Add do caption := TIdContext(List.Items[i]).Connection.Socket.Binding.PeerIP; end; IdTCPServer1.Contexts.UnlockList; end;
Delphi-Quellcode:
und OnDisconnet;
procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
begin Log.Lines.Add('Verbindung: ' + AContext.Binding.PeerIP); end;
Delphi-Quellcode:
procedure TForm1.IdTCPServer1Disconnect(AContext: TIdContext);
begin Log.Lines.Add('Verbindungsabbruch: ' + AContext.Binding.PeerIP); end; Mache ich hier irgendwo einen Fehler? Der Client der die Daten schickt bleibt ständig verbunden und zeigt auch weiterhin verbunden an, obwohl er im Server nicht mehr sichtbar ist (ich schicke vom Client aus zwischendurch eine Nachricht um festzustellen ob er noch lebt)... Wer kann mir helfen? Vielen Dank im voraus Andreas |
Re: Indy10 IdTCPServer Problem
Die VCL ist nicht Threadsicher, benutze deshalb Kritische Abschnitte.
Delphi-Quellcode:
uses ..., SyncObjs;
type : private { Private-Deklarationen } FCriticalSection:TCriticalSection; : end; implementation procedure TForm1.FormCreate(Sender: TObject); begin FCriticalSection:=TCriticalSection.Create; end; procedure TForm1.FormDestroy(Sender: TObject); begin FCriticalSection.free; end; procedure TForm1.IdTCPServer1Execute(AContext: TIdContext); : begin : FCriticalSection.Enter; try ListView1.Clear; List := IdTCPServer1.Contexts.LockList; for i := 0 to List.Count - 1 do begin TidContext(List.Items[i]).Connection.IOHandler.WriteLn(text); with Listview1.Items.Add do caption := TIdContext(List.Items[i]).Connection.Socket.Binding.PeerIP; end; IdTCPServer1.Contexts.UnlockList; finally FCriticalSection.Leave; end; end; |
Re: Indy10 IdTCPServer Problem
Hallo,
vielen Dank für die schnelle Antwort. Ich habe es gleich ein gebaut... Nun muss ich nur mal noch ne einfach Erklärung finden, was genau diese Kritische Abschnitte sind und machen 8) Gruß Andreas |
Re: Indy10 IdTCPServer Problem
|
Re: Indy10 IdTCPServer Problem
Danke für den Link...
Aber der Server macht immernoch das gleiche. Wobei ich diesmal auch sehen konnte dass der Server eine CPU Last von 49% hatte als nichts mehr ging... Hat vielleicht noch jemand eine Idee??? Gibt es vielleicht eine gute Alternative zu den Indy-Komponenten die ich nutzen könnte? Gruß und Danke Andreas |
Re: Indy10 IdTCPServer Problem
hast du schon mal versucht den server zu debuggen?
also schritt für schritt durchgehen und schauen wann er hängen bleibt |
Re: Indy10 IdTCPServer Problem
Hallo gsh,
nein noch nicht wirklich. Das Problem tritt erst nach ca 45 min bis 1 Stunde auf. Ich werde nun mal jeden Schritt in ein Logfile eintragen. Vieleicht kommt dabei was zu Tage. Da er alle 3-4 Minuten Daten empfängt und diese dann an 3 Clients verteilt sind das viele Schritte die 1000 mal funktionieren und dann plötzlich nicht mehr :roll: Ich dachte, dass vielleicht jemand die Problematik hier bekannt ist... Ich werde nun mal das Logfile integrieren und dann mal schauen ob es neue Erkenntnisse bringt. Gruß Andreas |
Re: Indy10 IdTCPServer Problem
So, neue Erkenntnisse aus dem Logfile....
Hier mal zuerst die Auszüge aus dem Logfile wie es regelmäßig erscheint und auch in Ordnung ist:
Delphi-Quellcode:
09.11.2008 14:39:17: OnExecute durch: 127.0.0.1
09.11.2008 14:39:28: 192.168.100.207: NOOP: 09.11.2008 14:39:28: 192.168.100.207: CriticalSecion Enter passed 09.11.2008 14:39:28: 192.168.100.207: Contexts.LockList passed 09.11.2008 14:39:28: Schleife beginnt 09.11.2008 14:39:28: 127.0.0.1(0): WriteLN passed 09.11.2008 14:39:28: 192.168.100.207(1): WriteLN passed 09.11.2008 14:39:28: 192.168.100.65(2): WriteLN passed 09.11.2008 14:39:28: 127.0.0.1: NOOP: 09.11.2008 14:39:28: Schleife Ende 09.11.2008 14:39:28: 192.168.100.207: Contexts.UnlockList passed 09.11.2008 14:39:28: 192.168.100.207: CriticalSecion.Leave passed Und so sieht es aus wenn es kracht:
Delphi-Quellcode:
Hier ist auffällig, dass in einem OnExecute-Event plötzlich ein OnConnect und ein weiteres OnExecute ausgelöst wird. Hierbei kommt die Komponente wohl ins schleudern und bleibt stecken...
09.11.2008 14:39:28: OnExecute durch: 192.168.100.207
09.11.2008 14:39:43: 192.168.100.65: NOOP: 09.11.2008 14:39:50: OnConnect mit: 127.0.0.1 09.11.2008 14:39:50: OnExecute durch: 127.0.0.1 09.11.2008 14:39:50: 127.0.0.1: HELO:client 09.11.2008 14:39:58: 192.168.100.207: NOOP: Nur wie kann ich das verhindern??? Viele Grüße und Danke Andreas |
Re: Indy10 IdTCPServer Problem
Dann versuche mal, die gleiche Critical Section auch im OnConnect (und am besten auch im OnDisconnect) zu verwenden. Damit wird ausgeschlossen, dass eine Event eintritt, während ein anderes gerade behandelt wird ;)
|
Re: Indy10 IdTCPServer Problem
Dein Log-Objekt ist eine StringList, die ist auch nicht Threadsafe! Die ist mir gestern gar nicht weiter aufgefallen.
Eine andere Möglichkeit ist, wenn dein Server intern sowieso nur einmal betreten werden darf, die MaxConnection-Eigenschaft des Servers auf eins zu setzen. Das wird dann allerdings deine Verbidungsgeschwindigkeit drosseln, weil die Indys dann diesen Schutz für dich organisieren. Dies geht allerdings nur, wenn sich die Clients jedesmal an-/abmelden. |
Re: Indy10 IdTCPServer Problem
Hmm, eigentlich sollen sich mal später zwischen 20 und 30 Clients verbinden können ohne dass es Probleme gibt...
Wie benutze ich denn die gleiche CriticalSection nochmal? Einfach zu Beginn und am Ende ein Enter und ein Leave aufrufen? @omata Welches Log-Objekt meinst Du? Das Memo oder das Logfile das ich jetzt eingebaut habe? Wie komme ich denn nun weiter um das ganze stabil zum laufen zu bekommen? Danke nochmal und viele Grüße Andreas |
Re: Indy10 IdTCPServer Problem
Zitat:
Zitat:
|
Re: Indy10 IdTCPServer Problem
ok, wäre es dann vielleicht sinnvoll immer zu Beginn des Serverevents die CriticalSection zu beginnen und damit die anderen Threads warten zu lassen???
Oder bringt das wieder andere Probleme? |
Re: Indy10 IdTCPServer Problem
Ja entweder so, oder die schützt deinen Zugriff jeweils einzeln, damit nicht immer alle überall ausgesperrt werden.
Bau also einen Wrapper für das Log und schütze die Zugriffe auf dieses mit einem Kristischen Abschnitt und den Zugriff auf deine visuelle Komponente schützt du dann mit einem anderen Kritischen Abschnitt. |
Re: Indy10 IdTCPServer Problem
Zitat:
Ist so auch nicht richtig, du _darfst_ nur aus dem Mainthread auf Elemenate der VCL zugreifen. Das geht mittels Synchronize. Win32.API |
Re: Indy10 IdTCPServer Problem
Zitat:
|
Re: Indy10 IdTCPServer Problem
Hallo,
so wie es im Moment aussieht habe ich es nun geschafft dass es funktioniert. Ich habe für das schreiben der Logdatei eine Prozedur angelegt und dort eine eigene CriticalSection am Anfang und am Ende eingefügt. Im OnExecute schaue ich dann erst nach dem Kommando. Dann kapsele ich beim richtigen Kommando in einer eigenen CriticalSection den weiteren Ablauf. Zum testen habe ich eben mal einen Art Chatclient mit einem Timer, der jede Sekunde eine Zufallsnachricht an den Server schickt, programmiert und davon mal 10 Stück auf den Server losgelassen. Dabei ist nichts aus dem Ruder gelaufen. Nun habe ich den Server da laufen wo er hin soll... in ca. 1 Stunde weiß ich dann mehr. Gruß und Danke an alle die mir hier geholfen haben :cheers: Andreas |
Re: Indy10 IdTCPServer Problem
Zitat:
Wie schon gesagt: Mit Synchronize kann man eine Funktion im Kontext des Mainthreads ausfuehren. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:36 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