asio schleife
-
ich brauch hilfe beim erstellen einer asynchronen asio lese schreibschleife:
also ich hab mir das daytime 3 als server genommen.
es beginnt bei der funktion start.
nun soll ich es so funktionieren, dass es immer erst die komplette nachricht gelesen wird.
also async read soloange im handler ausgeführt wird bis der error angibt, dass die ganze nachricht gelesen wurde.
gleichzeitig soll eine nachricht gesendet werden.
Und sobald der write_handler ausgeführt wird, also die nachricht gesendet wird soll es wieder von vorn anfangen. das Problem ist nur, wie komm ich vom Handler wieder zurück zu start()?
ich kann sie ja nicht direkt in den handler schreiben, da dieser ja abgeschlossen werden muss.
die doc ist natürlich auch wertlos und ünötig kompliziert.
hat jemand eine idee?
-
Bei Asio nimmst du nicht wirklich eine Schleife. Du springst einfach von Handler zu Handler. Wenn du mit einem Client fertig bist, machst du einfach gar nichts mehr, dh. rufst keinen Handler mehr auf. Dank RAII wird aufgeräumt.
Wenn du weiter arbeiten willst, dann rufst du eben eben im letzten Handler wird dein Start auf.die doc ist natürlich auch wertlos und ünötig kompliziert.
Nicht wirklich, die Dokumentation von Asio ist echt angenehm.
-
ok, also
1. du meinst asio.post, oder?
2.ich hab noch das problem, dass ich, wenn ich das programm ein zweites mal starte, dass ich den Port ändern muss, damit es wieder funktioniert.
3. angenehm? es gibt ein biliges tutorial und ein paar Beispiele ohne die geringste erklärung?
oder hast etwa eine andere im sinn?
-
1. du meinst asio.post, oder?
Eher so (Pseudocode):
writeHandler() { reset(); async_read(getBuffer(), bind(this, readHandler)); } readHandler() { if(hasEnoughData()) { processResult(); async_write(getResultBuffer(), bind(this, readHandler)); } else { async_read(getBuffer(), bind(this, readHandler)); } } acceptHandler() { async_read(getBuffer(), bind(this, readHandler)); async_accept(bind(this, acceptHandler)); } ... async_accept(bind(shared_ptr<MyClass>(new MyClass), acceptHandler)); service.run(); ...2.ich hab noch das problem, dass ich, wenn ich das programm ein zweites mal starte, dass ich den Port ändern muss, damit es wieder funktioniert.
Ist doch Standard. Man kann nicht ohne weiteres 2 Programme an den selben Port binden. Das geht nur in Ausnahmefällen wie zb Multicast.
3. angenehm? es gibt ein biliges tutorial und ein paar Beispiele ohne die geringste erklärung?
oder hast etwa eine andere im sinn?http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio/reference.html
Die Tutorials (sind 12 und nicht 1) sind super dokumentiert und zeigen praktisch alles.
Die Beispiele erfordern halt ein Verständnis der Bibliothek an sich.
Boost.Asio ist halt keine einfache Bibliothek.
-
Ethon schrieb:
Nicht wirklich, die Dokumentation von Asio ist echt angenehm.
Netter Witz...
-
also über kreuz?
Nette Idee, hätt ich auch drauf kommen müssen, super, aber vielleicht würds mir tatsächlich gut tun noch mal die Klassenbasics zu studieren.
-
dann noch ne frage, wie aknn ich rausfinden ob die Verbindung beendet wurde?
-
alterbro schrieb:
dann noch ne frage, wie aknn ich rausfinden ob die Verbindung beendet wurde?
Da Du von "Verbindung" sprichst, nehme ich an, Du benutzt TCP.
Es kommt darauf an, wie sie beendet wurde. Wenn die Gegenseite sauber geschlossen wurde, dann kommt Dein read-Handler mit einem Fehler zurück. Solche Dinge wie das Ziehen des Netzwerksteckers bekommst Du nur zuverlässig heraus, in dem Du etwas über die Verbindung sendest. Du brauchst also z.B. einen Heartbeat, das Du zyklisch sendest. Wenn dabei ein Fehler auftritt, ist die Gegenseite tot.
-
also pseudo:
while(isinbuffer("keine angst ich bin noch da")){ lisindenbuffer(); schreibdemclient(); }q uit();oder so änhlich?
hab ich mir auch schon überlegt, aber ich dachte wenn asio mir das schon abgenommenhättte, wärs bandbreitenverschwendung.gut und vielleicht doch noch :
kann ich das programm so schreiben, dass wenn man auf das rote kreuz klickt, noch irgendwie gesendet wird:"bin dann mal weg", und das programm erst dann beendet wird?
-
Machs halt so: Der Client fragt regelmäßig beim Server nach, obs was Neues gibt. Der Server schmeißt alle Clients raus, die sich seit x Sekunden nicht mehr gemeldet haben.
kann ich das programm so schreiben, dass wenn man auf das rote kreuz klickt, noch irgendwie gesendet wird:"bin dann mal weg", und das programm erst dann beendet wird?
Da musst du in deine GUI-Bibliothek sehen, was sie in Sachen Quit-Handler anbietet.
-
ok, danke
-
noch irgendwie gesendet wird:"bin dann mal weg", und das programm erst dann beendet wird?
Ich weiss nicht, was du fuer vorstellungen von "Beenden" hasst, aber wenn beenden bei dir heisst, deinem Prozess einfahc die CPU zeit, Ressource und Speicher unterm A.... wegzuziehen, dann hasst natuerlich keine chance.
Aber normal wird beim Beenden noch ordnungsgemaess aufgeraeumt ... auch beim BS mit dem roten kreuz

Das heisst zumindest wuerden destrukturen durchlaufen ...Wenn du mit roten kreuz das close am Fenster meinst:
Dann heisst das rote kreuz auch nicht, das deine Main sofort abgewuergt wird, sondern es beideutet das ein WM Close an ein Fenster geschickt wird.
Das laesst sich abfangen, und auch wenn dein Mainfenster den Close schon bekommen hat, macht es noch andere dinge bevor es endgueltig im Nirvana verschwindet, und danach wird erst die main zuende gebracht. zigtausend möglichkeiten sich da noch einzuklinken.Wenn du mit rotem kreuz das Shutdown des BS meinst:
Egal ob Gui App oder Server ohne Konsole, dein BS schickt dir Signale in dem Fall, wenn das BS selber versucht dich zu beenden.
Zuerst versucht es das auf die Freundliche Art, also schickt dir nen Signal, was du handeln kannst, aka du kannst aufraeumoperationen anstossen ...
Wenn du da drauf ned reagierst, faehrt es haertere Geschuetze auf, und nen Boeses signal kommt, und deinem Prozess werden ressource und speicher einfach weggenommen
Wie genau das funktioniert, da musst bei den entsprechenden BS API's schauen.
Da gibts auch noch andere Wege.
z.b. unter windows, Dienste / Services (was das equivalent zu daemons ist), da bekommst ne eventschnittstelle, wo auf solche events auch hoeren und reagieren kanns.Trotzdem solltes den fall beruecksichtigen, dass dein Server / CLient einfach mal hängt ...
-
Oder bei SDL: Auf das SDL_Quit event reagieren, sonst beendet sich dein Program beim Klick auf das Kreuz gar nicht
