AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Pinger Tool

Ein Thema von Balthasar · begonnen am 19. Aug 2013 · letzter Beitrag vom 19. Aug 2013
Antwort Antwort
Balthasar

Registriert seit: 11. Jan 2009
9 Beiträge
 
#1

Pinger Tool

  Alt 19. Aug 2013, 19:09
Hallöchen! Ich versuche in Delphi ein Chat-Programm zu realisieren und arbeite mit den alten ClientSocket und ServerSocket Komponenten. Im Moment hänge ich bei folgendem Problem:
Meine Klasse TPinger leitet sich von TThread ab, ich versuche zu jeder vollen Sekunde alle am Chat beteiligten Personen zu pingen. Die PING() Methode im Code unten macht lediglich folgendes: Socket.SendText('PING!');
Delphi-Quellcode:
procedure TPinger.Execute;
begin
    while not Terminated or (benutzer <> nil) or (benutzer.getSocket <> nil) do
    begin
      benutzer.PING();
      Sleep(1000);
    end;
end;
So weit so gut. Das Programm startet und läuft auch ohne Probleme, die Pings kommen zügig an und alles scheint bestens. Beim Disconnecten des Clients jedoch, crasht das Programm vollständig. Fehlermeldung gibt es keine direkt. Läuft die Anwendung außerhalb der Entwicklungsumgebung, so crasht sie einfach ("Projekt1.exe funktioniert nicht mehr und muss beendet werden."). Lasse ich das Projekt innerhalb der Entwicklungsumgebung zum Fehler kommen, poppt der Debugger auf und zeigt mir irgendeinen Assembler-Code oder so.

Mein Verdacht liegt darin, dass der Thread trotz Anweisung bei fehlendem "Benutzerobjekt" oder dem fehlenden Socket des Benutzerobjekts abzubrechen einfach nicht abbricht sondern ins leere tritt und stirbt. Jemand ne idee wie ich das Problem lösen könnte?

Mfg
Balthasar
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#2

AW: Pinger Tool

  Alt 19. Aug 2013, 19:14
Wie wäre es mit and?
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Balthasar

Registriert seit: 11. Jan 2009
9 Beiträge
 
#3

AW: Pinger Tool

  Alt 19. Aug 2013, 19:17
Wie wäre es mit and?
Der soll ja sofort aufhören wenn eines dieser Kriterien nicht mehr erfüllt wird. Mit AND würde er nur dann aufhören wenn alle 3 Fälle (oder je nach dem welche Fälle man bindet) eintreten.
  Mit Zitat antworten Zitat
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.336 Beiträge
 
Delphi XE2 Professional
 
#4

AW: Pinger Tool

  Alt 19. Aug 2013, 20:02
and ist schon richtig

wenn man es etwas umschreibt (nur zum Verständnis) dann wird's eindeutiger warum:

while (not Terminated) and (not benutzer = nil) and (not benutzer.getSocket = nil) do
Zitat:
solange (nicht Terminated) und (nicht benutzer = nil) und (nicht benutzer.getSocket = Nil)
Schleifeninhalt abarbeiten
Eine While-Schleife arbeitet solange, solange das Argument true ist
mfg
Helmi

>> Theorie ist Wissen, dass nicht funktioniert - Praxis ist, wenn alles funktioniert und keiner weiss warum! <<

Geändert von Helmi (19. Aug 2013 um 20:05 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#5

AW: Pinger Tool

  Alt 19. Aug 2013, 20:04
Wie wäre es mit and?
Der soll ja sofort aufhören wenn eines dieser Kriterien nicht mehr erfüllt wird. Mit AND würde er nur dann aufhören wenn alle 3 Fälle (oder je nach dem welche Fälle man bindet) eintreten.
So wie es dort steht heißt es aber, daß er solange weitermacht, wie eine der drei Bedingungen noch zutrifft.
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Balthasar

Registriert seit: 11. Jan 2009
9 Beiträge
 
#6

AW: Pinger Tool

  Alt 19. Aug 2013, 21:06
Komisch, vllt lebe ich in einer invertierten Welt

Vielen Dank bislang, aber es geht immer noch nicht, gleicher Fehler

Geändert von Balthasar (19. Aug 2013 um 21:08 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#7

AW: Pinger Tool

  Alt 19. Aug 2013, 23:07
Wenn dein Hauptformular geschlossen wird, solltest du den Thread(s) höflich mitteilen, dass jetzt Schluß ist:
Delphi-Quellcode:
mythread.Terminate; // setzt property Terminated auf True
Sleep(1050); // warten bis Thread sich selbst beendet hat
Grundsätzlich ist es gefährlich, wenn Threads weiterlaufen aber der Hauptthread terminiert wird.
Dazu musst du natürlich die Thread-Objekte in einer Variablen speichern, damit du beim Programmende darauf zugreifen kannst.
Der Sleep()-Aufruf ist zwar etwas primitiv, weil so die ganze Anwendung min. 1 Sekunde nicht reagiert aber als schnelle, einfache Lösung geht das schon.
Du kannst die Reaktionszeit bis die Threads auf das Terminate reagieren so verringern:
Delphi-Quellcode:
procedure TPinger.Execute;
var
  i : Integer;
begin
    i := 0;
    while not Terminated or (benutzer <> nil) or (benutzer.getSocket <> nil) do
    begin
      if i mod 5 = 0 then
         benutzer.PING(); // 1 Ping ungefähr alle 1000ms
      Inc(i);
      Sleep(200);
    end;
end;
fork me on Github
  Mit Zitat antworten Zitat
Balthasar

Registriert seit: 11. Jan 2009
9 Beiträge
 
#8

AW: Pinger Tool

  Alt 19. Aug 2013, 23:45
Wenn dein Hauptformular geschlossen wird, solltest du den Thread(s) höflich mitteilen, dass jetzt Schluß ist:
Delphi-Quellcode:
mythread.Terminate; // setzt property Terminated auf True
Sleep(1050); // warten bis Thread sich selbst beendet hat
Grundsätzlich ist es gefährlich, wenn Threads weiterlaufen aber der Hauptthread terminiert wird.
Dazu musst du natürlich die Thread-Objekte in einer Variablen speichern, damit du beim Programmende darauf zugreifen kannst.
Der Sleep()-Aufruf ist zwar etwas primitiv, weil so die ganze Anwendung min. 1 Sekunde nicht reagiert aber als schnelle, einfache Lösung geht das schon.
Du kannst die Reaktionszeit bis die Threads auf das Terminate reagieren so verringern:
Delphi-Quellcode:
procedure TPinger.Execute;
var
  i : Integer;
begin
    i := 0;
    while not Terminated or (benutzer <> nil) or (benutzer.getSocket <> nil) do
    begin
      if i mod 5 = 0 then
         benutzer.PING(); // 1 Ping ungefähr alle 1000ms
      Inc(i);
      Sleep(200);
    end;
end;
Das ist ein wirklich sehr guter Vorschlag, ich danke vielmals.
Mittlerweile ist mein Problem auch komplett gelöst, im While-Block fehlte lediglich eine weitere Bedingung an die ich anfangs nicht dachte: (benutzer.getSocket.connected).
Mittlerweile kämpfe ich gegen andere Probleme, aber die schaffe ich schon wenn ich etwas mehr beider Sache bin
Danke nochmals an alle Helfer!!
  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 18:10 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