Seite 1 von 1
Thread durch anderen Thread beenden.
Verfasst: 10. Juni 2009 13:44
von Nailgun
Hey Leute
ich hab nen Problem mit dem Beenden von Threads.
Ich hab einen Server, der für jeden anfragenden Client einen eigenen Thread aufmacht (ich muss hier Threads nehmen, weil ich auf ner Multicore Maschine unterwegs bin). Jetzt gibt es eine Vorgabe, dass sich nur ein Client verbinden kann, wenn seine Gegestelle(anderer Client) schon vom Server angenommen wurde, oder sich innerhalb einer bestimmten Zeit noch verbinden wird. Wenn sich jetzt einer dieser Clients abmeldet muss das seine Gegenstelle mitbekommen. Und genau hier steh ich aufm Schlauch. Wenn sich ein Client abmeldet wird das durch einen Slot des Servers erkannt und dieser Thread wird beendet. Jetzt muss aber noch der Thread der Gegenstelle beendet werden. Hat jemand ne Idee, Anregung oder nen Tipp? Wär euch echt dankbar!
mfg Chris
Verfasst: 10. Juni 2009 13:58
von franzf
Also, so weit ich das sehe hat das nichts mit "Thread beendet Thread" zu tun, sondern "Server schickt Beenden-Signal an Client".
Und "ich habe Multicore-Server, drum muss ich Threads verwenden" leuchtet mir ebenso wenig ein wie "Ein eigener Thread pro anklopfendem Client, wobei nur ein Client gleichzeitig erlaubt ist".
Verfasst: 10. Juni 2009 14:05
von Nailgun
ich weiss nicht ob ich mich da falsch ausgedrückt hab. es soll nicht nur ein client erlaubt sein, sondern beliebig viele. und das signal soll nicht an den client geschickt werden, sonden es soll der thread beendet werden.
es sollen n p2p verbindungen erlaubt sein. wenn nun eine peer beendet wird oder abraucht soll das die andere peer natürlich mitbekommen.
Verfasst: 10. Juni 2009 14:22
von franzf
Achso.
A,B:Client, S:Server
A verbindet sich zu B und meldet sich dann beim Server an. Wenn ich das richtig verstanden habe wird A abgeblockt, wenn er nicht an irgend einem Client schon geknüpft ist.
Jetzt trennt sich B aus dem Netzwerk. S registriert dies und beendet den Thread, in dem B in S rumgewerkelt hat.
Und du willst jetzt, dass A mitbekommt, dass B weg ist? (Hat denn auch B in A einen Thread? oder nur B in S).
Wenn ja, ist das auch Sache des Protokolls, da A auf nem anderen Rechner im Netzwerk unterwegs ist als S. Und damit wären wir bei einem Signal "S:A->ClientStopped(UId_von_B)", oder selbes Signal von "B->A".
Wenn der B-Thread in S dem A-Thread in S mitteilen soll dass B weg ist, dann ist das eigentlich interne Angelegenheit der Serversoftware, welche entweder mit eigenen Signals/Slots, oder sogar direkten Methodenaufrufen zu lösen ist.
Oder hab ich immer noch was falsch verstanden?
Verfasst: 10. Juni 2009 14:31
von Nailgun
hm ich glaub nicht so richtig

ich versuchs nochmal.
Client A;B
Server S
A möchte sich mit B verbinden. A meldet sich deswegen bei S an und wartet eine bestimmte Zeit ob sich B auch verbunden hat. Hab sich A und B innerhalb dieser Zeit bei S angemeldet so gelten die Verbindungen zwischen A-S und B-S als aufgebaut. S hat für A und B jeweils einen Thread gestartet. Wenn sich jetzt A oder B abmeldet soll die Gegenstelle(A oder B) das natürlich mitbekommen. Da ein Client bei mir nicht aktiv hört würde er es auch nicht mitbekommen wenn S an einen Client sendet dass die Gegenstelle weg ist.
Also wenn sich jetz zum Beispiel B abmeldet oder einfach beendet wird, so wird das in einem Slot von S erkannt und der Thread von B wird beendet. Aber wie kann ich jetzt die Verbindung zwischen S-A jetzt schliessen und den Thread von A beenden damit der Client das auch mitbekommt.
Hoffentlich hab ich es jetzt verständlich heschildert :;-)
Danke franzf
*edit*
B hat in A keinen Thread. Es ist so wie du am Ende geschrieben hast.
Ich kann den Thread zwar aus meiner Hash rausschmeissen. damit ist er aber nicht beendet. und ein quit, exit oder terminate lässt er mir nicht zu...
*edit2*
Sorry franzf ich kann die Threads schon beenden. Mein Code war vom rumprobieren vermurkst. Aber jetzt hab ich das Probelm das im ersten Beitrag erwähnt hast. Der Thread von A wird beendet aber der Client A bekommt nicht mit dass der Socket geschlossen wurde. Ich ruf aber vor dem beenden des Client noch die disconnectFromHost auf, aber er bekommt es ned mit. Kannst mir da vielleicht helfen?
Verfasst: 10. Juni 2009 15:00
von franzf
Nailgun hat geschrieben:B hat in A keinen Thread. Es ist so wie du am Ende geschrieben hast.
Ich kann den Thread zwar aus meiner Hash rausschmeissen. damit ist er aber nicht beendet. und ein quit, exit oder terminate lässt er mir nicht zu...
Wenn also B terminiert kannst du am Server den Thread von B beenden, das Beenden des Server-Threads für A klappt aber nicht?
Funny, dann brauch ma mal Code...
Und wg. Protokoll:
Irgend was werden deine Clients doch voneinander wollen

"A an B, gib mir Porn P", "B an A, berechne 'sin(x)-x^2'", usw.
Oder sitzen die nur rum und idlen, bis sich jemand disconnected, dass se was zu tun bekommen?

Es wird also sowieso irgend eine "Infrastruktur" nötig sein, mit der die einzelnen Clients untereinander ihre Wünsche kundtun können, aber auch mitteilen, wenn es eine Antwort gibt. Und genau in dieses Geflecht könnte (sollte) man auch Möglichkeiten zur Steuerung von cennects und disconnects einbauen.
Z.B. wenn keine Anfragen oder Daten über einen bestimmten Zeitraum von A nach B laufen, B bei A anfrägt "Hey A, hierB: lebst du noch?" Und wenn in einem bestimmten Zeitraum keine Antwort kommt wird hier terminiert. Solche Kommunikation kann natürlich auch über den Server laufen.
Verfasst: 10. Juni 2009 15:12
von franzf
Nailgun hat geschrieben:Der Thread von A wird beendet aber der Client A bekommt nicht mit dass der Socket geschlossen wurde. Ich ruf aber vor dem beenden des Client noch die disconnectFromHost auf, aber er bekommt es ned mit. Kannst mir da vielleicht helfen?
Also das disconnected()-Signal des Socket auf Client-Seite wird nicht ausgelöst? Kannst du mal bissl Code zeigen (den wo der Server den Thread beendet, wie du die Verbindung beendest, wie der Client die Connections zum Server managed, usw)
Du kannst zum Testen ja auf client und serverseite das error()-Signal des Sockets abfangen, vllt. gibts was interessantes!
Verfasst: 10. Juni 2009 15:14
von Nailgun
Ist es normal dass ich nen timer mitlaufen lassen muss um sowas abzufangen? wenn ich ne verbindung zwischen zwei sockets hab einer davon schliest die verbindung, bekommt das der andere dann nicht mit?
hab mir das so vergestellt, dass wenn sich B verabschiedet, dann beendet der Server den Thread von B. Dann wird erst die Verbindung zwischen dem ServerSocket A und dem ClientSocket A geschlossen und dann der Thread von A beendet. D.H wenn der Server die Verbindung der Socktes schliesst kann das mein Client A gar nicht mitbekommen?
Verfasst: 10. Juni 2009 15:18
von franzf
Nailgun hat geschrieben:hab mir das so vergestellt, dass wenn sich B verabschiedet, dann beendet der Server den Thread von B. Dann wird erst die Verbindung zwischen dem ServerSocket A und dem ClientSocket A geschlossen und dann der Thread von A beendet. D.H wenn der Server die Verbindung der Socktes schliesst kann das mein Client A gar nicht mitbekommen?
Da hast du schon recht, wenn die Verbindung abgebrochen wird, kommt das disconnected() Signal. Aber scheinbar gibts da auch irgend welche Probleme?
Verfasst: 10. Juni 2009 15:32
von Nailgun
Hab grad nochmal in meine Sources geschaut. Ich hab das disconnected() Signal mit dem quit() Slot des Threads connected. Denk ich is ja auch naheliegend. wenn ich jetzt von Client aus das disconnectFromHost() aufrufe bekomm ich das am Server mit und der Thread wird beendet. Ruf ich im Slot der das Beendeneines Threads abfangt, die disconnectFromHost eines Sockets auf passiert nix.
Hm scheint echt ein Problem zu sein, oder ich habs voll vermurkst
Danke dir franzf, wenn ich ne Lösung hab schreib ich se hier rein.
Verfasst: 12. Juni 2009 04:24
von speedy
Hmm
also ich bin da ja kein Experte ...
aber Ich hab ja auch ein Server Client Programm gemacht.
Da hab ich auch immer so anfragen laufen ob die gegenstelle noch da ist ( bei mir ist das PING und PONG.
Mir ist schon ufgefallen das die sonst nicht immer mitbekommen ob die gegenstelle da ist ... z.B. Netzwerkkabel abgeszogen aber Programme meinen immer noch eine Verbindung zu haben.
Merken die dann erst wenn sie daten senden wollen ( glaub ich).
Ich hab das mit einem QTimer gemacht. Wenn nach einem PING (und Timer->start(5000) ) eine gewisse zeit vorbei ist (hier 5 sec) und kein PONG gekommen ist. Vermute ich das die gegenstelle nicht mehr da ist oder nicht mehr erreichbar ist.
Der QTimer könnte dann ja bei dir den Thread auch beenden.
Verfasst: 12. Juni 2009 09:38
von Nailgun
@ speedy
danke ich werd da drüber nachdenken. aber ich glaub es wird kein weg dran vorbeiführen sowas einzubauen.
Verfasst: 15. Juni 2009 11:40
von Nailgun
Also ich hab ne Lösung gefunden.
1. Zum Schliessen der Sockets aufm Server:
mit invokeMethode geht das, hät ich auch gleich draufkkommen können.
2. Erkennen wenn eine Verbindung abgebrochen ist:
es wäre viel schöner das mit einem PingPong zu machen, aber bei mir reicht es wenn ich einen Timer mitlaufen lass der sich jedesmal zurück setzt wenn von Client einen Nachricht gekommen ist. überschreitet der Timer einen gewissen Wert so gilt die Verbindung als abgebrochen.
Vielen Dank nachmal an euch.