![]() |
Indy -IdTcpServer führt zu 100% CPU -Last
Hi Leute,
ich bin's mal wieder mit einer Indy-Frage, ich kämpfe jetzt schon sehr lange mit den Indy-Komponenten, aber manchmal könnte ich das Blocking Sockets verfluchen. Warum haben die sich dafür entschieden ? Aufgabe: Bildübertragung eines Webcam-Bilds so gut und schnell wie möglich. Problem: Im Moment verwende ich produktiv gerade ein eigenes Protokoll das noch sehr viel Overhead hat. Aber 4 Leute können problemlos mein Bild betrachten. Jetzt habe ich mein Protokoll wirklich auf das wichtigste beschränkt die Bildübertragung. Code Beispiel Server :
Code:
Code Bsp. Client :
Var ms : TMemoryStream;
ImgWrapper : TImageWrapper; sCmd : String; begin // Speicher zur Bildablage im Stream erzeugen ms := TMemoryStream.Create; // KLasse zum Abgreifen des Video-Bild erzeugen imgWrapper := TImageWrapper.Create(AThread,frmMain.Video); try imgWrapper.FileSys := bFileSys; imgWrapper.Kompression := Einstell.Compression; // Bildkompression setzen // Solange eine Socket-Verbindung besteht jetzt das Bild zum Kunden übertragen While (AThread.Connection.Connected) do begin // MemoryStream leeren ms.clear; // aktuelles Bild jetzt laden/abgreifen if imgWrapper.loadImage then begin // Geladenes Bild in Strean schreiben imgWrapper.WriteToStream(ms); // Bildspeicherposition auf den Anfang setzen ms.Position := 0; // Bild einfach in den Buffer schreiben und abschicken // durch die entsprechenden Parameter in WriteStream, // steht in den ersten vier Bytes des Streams die Stream Grösse try AThread.Connection.OpenWriteBuffer; AThread.Connection.WriteStream(ms,true,true); AThread.Connection.CloseWriteBuffer; except logf.log('Versuche Write Buffer zu canceln',1); //AThread.Connection.CancelWriteBuffer; AThread.Connection.ClearWriteBuffer; //AThread.Connection.DisconnectSocket; end; end else begin // es konnte kein Bild geladen werden, es wird jetzt der leere Stream zum Client geschickt // der überprüft anhand der Streamgrösse ob er darauf reagiert, so wird der normale // Befehlsablauf nicht unterbrochen AThread.Connection.OpenWriteBuffer; try AThread.Connection.WriteStream(ms,true,true); AThread.Connection.CloseWriteBuffer; except //AThread.Connection.CancelWriteBuffer; AThread.Connection.ClearWriteBuffer; end; logf.log('Send empty stream size 0',1); end; end; finally // Speicher wieder freigeben ms.Clear; FreeAndNil(ms); FreeAndNil(ImgWrapper); end;
Code:
Wie Ihr seht beschränkte ich mich jetzt auf die reine Bildübertragung, das Problem dabei ist, das das Bild zwar super schnell und super flüssig wird, aber ab dem dritten User beim Server die CPU Last auf 100% steigt und ich nicht nachvollziehen kann warum.
// die Procedure StreamNow wird innerhalb des VideoStreamThread immer wieder aufgerufen
procedure TVideoStreamThread.StreamNow; begin // Speicher leeren ms.Clear; // try if (TcpCon.Connected) and (not Terminated) then begin try TcpCon.ReadStream(ms); except ms.clear; end; if ms.Size > 0 then begin // Stream Position auf null, damit vom Anfang gelesen wird ms.Position := 0; jpg.LoadFromStream(ms); // Haben wir ein gültiges Jpg if not jpg.Empty then begin aktJpg := jpg; // Jpg zeichnen Synchronize(PaintImage); end; end; end; finally // Memory-Stream leeren ms.clear; end; end; In meinen Logfile steht kein einziger Fehler von irgenteinem Thread, kann es sein das diese intensiven Threads für Windows bzw. Indy zuviel sind ? Jeder Kommentar hilft vielleicht weiter, sitze schon etwas länger darüber und komme jetzt gerade nicht weiter. Und das ist echt frustierend bin schon am überlegen, ob ich das ganze Projekt auf die ICS-Komponenten umschreibe, aber das würde etwas dauern und ich habe mit denen auch noch keinerlei Erfahrung. Was sagt Ihr ? Danke Data |
Re: Indy -IdTcpServer führt zu 100% CPU -Last
Fehler gefunden ! Dank an Luckie :hello:
Kleiner Tipp für alle die mal mit ähnlichen Problemen kämpfen sollten : Auch Festplattenzugriffe(egal ob Lesen oder Schreiben) innerhalb eines Threads sollten unbedingt syncronisiert werden :warn: Das war in meiner ImageWrapper-Klasse in der Methode LoadImage nicht der Fall. Gruß Data |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:20 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