Probleme mit select() und nichtblockierendem Socket
Posted: 06. Oct 2010 19:45
Ich glaube, ich habe hier ein grundsätzliches Verständnisproblem:
Ich habe einen Server, bei dem ich mit select() auf eingehende Daten und neue Verbindungen checke. Das funktioniert prinzipiell auch ganz gut. Sockets von eingehenden Verbindungen werden immer auf non-blocking gesetzt, so dass ich kontrollieren kann, wie lange die Empfangsroutine dauert (da ich nicht unbegrenzt lange an größeren Datenblöcken herumladen will und dabei die anderen Clients vernachlässige).
Das führt jetzt allerdings zu folgendem Effekt, wenn ein Client nach dem Connect sehr schnell Daten sendet:
1. select() kommt zurück, weil sich ein Client verbindet -> dieser wird akzeptiert
2. der Socket dieses Clients wird auf non-blocking gesetzt
3. es wird versucht, Daten mit recv() zu empfangen -> es wird nichts empfangen, recv() kehrt sofort zurück
4. es wird erneut select() aufgerufen -> dieses blockiert jetzt bis in alle Ewigkeit
Scheinbar sind die Daten schon da, so dass select() nichts mehr melden kann, recv() konnte sie aber noch nicht abholen.
Was nun? Wie erfahre ich, ob irgend einer der Sockets noch nicht empfangene Daten hat, wenn ich select() dafür nicht verwenden kann?
Ich habe einen Server, bei dem ich mit select() auf eingehende Daten und neue Verbindungen checke. Das funktioniert prinzipiell auch ganz gut. Sockets von eingehenden Verbindungen werden immer auf non-blocking gesetzt, so dass ich kontrollieren kann, wie lange die Empfangsroutine dauert (da ich nicht unbegrenzt lange an größeren Datenblöcken herumladen will und dabei die anderen Clients vernachlässige).
Das führt jetzt allerdings zu folgendem Effekt, wenn ein Client nach dem Connect sehr schnell Daten sendet:
1. select() kommt zurück, weil sich ein Client verbindet -> dieser wird akzeptiert
2. der Socket dieses Clients wird auf non-blocking gesetzt
3. es wird versucht, Daten mit recv() zu empfangen -> es wird nichts empfangen, recv() kehrt sofort zurück
4. es wird erneut select() aufgerufen -> dieses blockiert jetzt bis in alle Ewigkeit
Scheinbar sind die Daten schon da, so dass select() nichts mehr melden kann, recv() konnte sie aber noch nicht abholen.
Was nun? Wie erfahre ich, ob irgend einer der Sockets noch nicht empfangene Daten hat, wenn ich select() dafür nicht verwenden kann?