Herakles
Profifragensteller
Hallo liebe Hobbybastler!
Ich schraube gerade ein wenig an termios(3) herum und mache da interessante Entdeckungen, die mir gar wahrlich Freude bereiten. Folgenes Szenario:
Ich lese von der USB-Schnittstelle serielle Daten(btw.: unter Linux, nicht hauen!
). Diese kommen in Paketen zu 514 Bytes hereingesaust. Damit ich auf meinem nonblocking-socket nicht bei einem read(2) 0 Bytes lese, habe ich ein select(2) vorgeschaltet, dass nur auf dem seriellen Socket lauscht, ob Daten da sind. Wenn dem so ist, greife ich diese mit read(2) ab.
Nun besagt ja die manpage von read(2), dass "up to count bytes" gelesen werden - sprich "bis zu" und nicht "mindestens". Jetzt mache ich folgende Beobachtung:
Wenn mein select reagiert und ich zum Codeteil mit dem read(2) komme, dann bekomme ich in der Regel 496 Bytes zum Lesen. Kleine, aber feine Messungen mit gettimeofday(2) haben mir aber gezeigt, dass die 18 fehlenden Bytes (514-496 = 18) ohne nennenswerte Verzögerung verfügbar sind (zwischen zwei 514-bytes Paketen liegen etwa 25ms, zwischen einem gelesenen 496-Bytes und einem 18-Bytes Paket nur rund 1ms).
Meine Idee nun: select(2) reagiert darauf, dass die "ersten" Daten des Pakets am Socket verfügbar sind und read(2) greift diese ab. Wenn read(2) nun aber den Puffer des Sockets geleert hat, sind noch Daten auf der Leitung, die aber noch nicht im Puffer sind. Also werden die beim nächsten select(2) bemerkt und read(2) greift sie ab. So entstehen dann zwei Datenblöcke - einer mit 496 Bytes und einer mit 18 Bytes.
Was aber, wenn ich alle Daten in einem Rutsch mit read(2) abholen will? Ein usleep(1000) direkt zwischen dem select(2) und dem read(2) erweist mir den Dienst - read(2) findet die vollen 514 Bytes vor. Das erscheint mir aber doch als merkwürdiger Workaround. Hat jemand eine bessere Idee?
Viele Grüße
Herakles
EDIT: Ich meine natürlich nicht einen Socket, sondern einen Filedeskriptor, den ich mit open(2) angelegt habe...
Ich schraube gerade ein wenig an termios(3) herum und mache da interessante Entdeckungen, die mir gar wahrlich Freude bereiten. Folgenes Szenario:
Ich lese von der USB-Schnittstelle serielle Daten(btw.: unter Linux, nicht hauen!
). Diese kommen in Paketen zu 514 Bytes hereingesaust. Damit ich auf meinem nonblocking-socket nicht bei einem read(2) 0 Bytes lese, habe ich ein select(2) vorgeschaltet, dass nur auf dem seriellen Socket lauscht, ob Daten da sind. Wenn dem so ist, greife ich diese mit read(2) ab.Nun besagt ja die manpage von read(2), dass "up to count bytes" gelesen werden - sprich "bis zu" und nicht "mindestens". Jetzt mache ich folgende Beobachtung:
Wenn mein select reagiert und ich zum Codeteil mit dem read(2) komme, dann bekomme ich in der Regel 496 Bytes zum Lesen. Kleine, aber feine Messungen mit gettimeofday(2) haben mir aber gezeigt, dass die 18 fehlenden Bytes (514-496 = 18) ohne nennenswerte Verzögerung verfügbar sind (zwischen zwei 514-bytes Paketen liegen etwa 25ms, zwischen einem gelesenen 496-Bytes und einem 18-Bytes Paket nur rund 1ms).
Meine Idee nun: select(2) reagiert darauf, dass die "ersten" Daten des Pakets am Socket verfügbar sind und read(2) greift diese ab. Wenn read(2) nun aber den Puffer des Sockets geleert hat, sind noch Daten auf der Leitung, die aber noch nicht im Puffer sind. Also werden die beim nächsten select(2) bemerkt und read(2) greift sie ab. So entstehen dann zwei Datenblöcke - einer mit 496 Bytes und einer mit 18 Bytes.
Was aber, wenn ich alle Daten in einem Rutsch mit read(2) abholen will? Ein usleep(1000) direkt zwischen dem select(2) und dem read(2) erweist mir den Dienst - read(2) findet die vollen 514 Bytes vor. Das erscheint mir aber doch als merkwürdiger Workaround. Hat jemand eine bessere Idee?
Viele Grüße
Herakles
EDIT: Ich meine natürlich nicht einen Socket, sondern einen Filedeskriptor, den ich mit open(2) angelegt habe...
Last edited: