[Socket] Daten empfangen im Hintergrund
-
Hallo Leute,
arbeite mich gerade in die Socket-Programmierung ein und bin nun mit folgendem Tutorial fertig geworden: http://c-worker.ch/tuts/select.phpDas Beispiel für den Server der mehrere Clients behandelt kann ich nun nachvollziehen. Ich möchte aber wissen wie ich einen Clienten implementieren kann, der nicht darauf wartet bis er Daten empfangen hat, sondern einfach weiter macht wenn momentan nichts ankommt.
Ich habe schon ungefaehr das was ich wollte. Ich habe den Client-Socket auf den Non-Blocking Modus umgestellt:
u_long iMode=1; ioctlsocket(Socket,FIONBIO,&iMode);Jetzt habe ich das Problem das ich gar nichts mehr empfangen kann, obwohl der Server Daten sendet. Gibt es da keine Möglichkeit dem Client zu sagen "Empfange Daten weiterhin im Hintergrund und gebe die Daten beim nächsten Aufruf von recv aus" ?
Ich dachte daran den recv Prozess im Blocking-Modus über einen Thread laufen zu lassen. Ist das eine gute Idee oder gibt es bessere Möglichkeiten?
Ich hoffe ich konnte mein Problem deutlich darstellen. Bedanke mich schon mal im voraus!
-
Man kann
selecteine maximale Wartezeit geben, die auch 0 sein darf. So kann der Client regelmäßig prüfen, ob etwas angekommen ist.
-
Wenn bei mir der Client einfach weitermachen, aber auf Daten vom Server reagieren soll, habe ich einen Client-Thread gebaut der die Daten annimmt und welcher eine Callback-Funktion ausführt (wenn die Daten anliegen). Der weiterarbeinde Thread muss aber unterbrechbar sein oder auf Events reagieren können. Unter einem Betriebssystem wie z.B. Windows sollte das über ein entsprechendes Event keine Probleme verursachen.
-
sondern einfach weiter macht wenn momentan nichts ankommt.
Generell gibts hier schon 2 grobe wege:
- Polling
- NebenläufigkeitWas du vorhasst, zaehlt unter Polling.
Vorteil:
- Du brauchst dich ned um konkurrierenden Ressourcenzugriff kuemmern.
- Du kannst die timeout funktionen nutzen, welche quasi Standard in den plattformunabhaengigen API's sind.Nachteil:
- Wenn man nicht aufpasst, kann es in die ressourcen gehen.
- wenig entkopplung der jobs untereinander (laufen alle im selben thread) .. sollten sich also kooperativ verhalten (focus nicht minutenlang belegen, etc)
- du kannst nur die internen puffer der sockets nutzen, welche recht gering sind. d.h. blockiert dich nen anderer job, und in der zwiaschenzeit sendet nen client ordentlich daten, kann es zu datenverlust kommen.Für nebenläufigkeit gibts eigentlich auch 2 varianten.
- du nutzt selber threads:Nachteil:
- du musst dich mit dem Ressourcenhandling und generell Threadproblemen auseinander setzen.Vorteil:
- flexibelster Ansatz
- kannst mehrere Kerne nutzen
- langwierige Jobs (lange berechnungen etc) sind einfacher und uebersichtlicher zu implementieren
- du kannst datenverlust vorbeugen, selbstverwaltete puffer, und du hasst definierte rechenzeit fuer den lesethread. geht natuerlich auf den speicher ...die 2.te Variante ist nen zwischending zwischen non thread und thread programmierung.
DIe meisten OS bieten assynchrone lese/schreiboperationen auf streambasierte ressourcen an. d.h. das betriebssystem baut dir die assynchronitaet.
wenn daten vorhanden sind, und dein mainthread (einziger thread) in einem unterbrechhbaren Zustand ist, wird die von dir definierte funktion zum lesen/schreiben gefeuert .... und zwar im context fon deinem thread. aka du hasst kein multithreading, d.h. die threadprobleme sind aussen vor.
Das OS uebernimmt quassi das polling fuer dich (nein es pollt nicht, sondern nutzt selber prozesse/threads und events) ist damit effizienter als polling.Nachteil:
Diese operationen sind meist OS spezifisch, also nicht plattformunabhanegig und pro plattform gibts mehr oder weniger einschränkungen ...Was das richtige fuer dich ist ?
Keine Ahnung ^^kommt drauf an ..
- willst ueben, dann wuerd ich dir die non thread versionen zuerst empfehlen
- willst maximale flexiblilitaet und spaetere erweiterbarkeit, wirst um threads nicht herumkommen
- fuer kleinere tools / aufgaben mit ueberschaubaren nebentaetigkeiten(neben den lesen und schreiben auf die sockets) kann threading aber schon overhaed sein, da ist polling schon ne option, wenn man plattformunabhaengig bleiben will/muss ...Ciao ...
-
- willst maximale flexiblilitaet und spaetere erweiterbarkeit, wirst um threads nicht herumkommen
Ich denke das dürfte eher hinkommen. Es geht darum zunächst einmal Positions-Daten ( X,Y,Z -Koordinaten ) zwischen zwei Clients über einen Server auszutauschen. Das ganze Szenario läuft lokal ab ( also 3 Laptops, nicht über Internet ). Ich will das ganze nur für Windows realisieren ( ohne zusätzliche Libraries )
edit: Und da der Server auch mal nichts senden kann und ich nicht im Client ständig darauf warten möchte bis recv was zurückliefert, dachte ich ich stelle diesen Vorgang in einen Thread hinein während meine main mit anderen Aufgaben weitermacht.
edit²: Danke, hat mit den Threads geklappt, jetzt kann ich weiterhin Daten empfangen ohne im main darauf zu warten
