AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Indy -IdTcpServer führt zu 100% CPU -Last
Thema durchsuchen
Ansicht
Themen-Optionen

Indy -IdTcpServer führt zu 100% CPU -Last

Ein Thema von DataCool · begonnen am 19. Nov 2003 · letzter Beitrag vom 19. Nov 2003
Antwort Antwort
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#1

Indy -IdTcpServer führt zu 100% CPU -Last

  Alt 19. Nov 2003, 00:49
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:
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 Bsp. Client :
Code:
// 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;
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.
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
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#2

Re: Indy -IdTcpServer führt zu 100% CPU -Last

  Alt 19. Nov 2003, 15:27
Fehler gefunden ! Dank an Luckie

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

Das war in meiner ImageWrapper-Klasse in der Methode LoadImage nicht der Fall.

Gruß Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:37 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