select (), recv () und EWOULDBLOCK für nicht blockierende Sockets

8

Ich würde gerne wissen, ob das folgende Szenario echt ist?!

  1. select () (RD) bei nicht blockierendem TCP-Socket besagt, dass der Socket bereit ist
  2. nach recv () würde EWOULDBLOCK trotz des Aufrufs von select ()
  3. zurückgeben
mrvincenzo 26.05.2009, 16:25
quelle

7 Antworten

1

Ich bin mir eines Fehlers in einem populären Desktop-Betrieb bewusst, wo O_NONBLOCK TCP-Sockets, insbesondere jene, die über die Loopback-Schnittstelle laufen, manchmal EAGAIN von recv() zurückgibt, nachdem select() meldet, dass der Socket zum Lesen bereit ist . In meinem Fall geschieht dies, nachdem die andere Seite den sendenden Strom halb geschlossen hat.

Weitere Informationen finden Sie im Quellcode für t_nx.ml in der NX-Bibliothek meiner OCaml Network Application Environment-Distribution. ( Link )

    
james woodyatt 26.05.2009, 22:52
quelle
4

Für recv() würden Sie EAGAIN anstatt EWOULDBLOCK erhalten, und ja, es ist möglich. Da Sie gerade mit select() überprüft haben, ist eines von zwei Dingen passiert:

  • Etwas anderes (ein anderer Thread) hat den Eingabepuffer zwischen select() und recv() .
  • geleert
  • Für den Socket wurde ein Empfangszeitlimit gesetzt, und es ist abgelaufen, ohne dass Daten empfangen wurden.
dwc 26.05.2009 16:32
quelle
2

Es ist möglich, aber nur in einer Situation, in der mehrere Threads / Prozesse versuchen, vom selben Socket zu lesen.

    
Harper Shelby 26.05.2009 16:28
quelle
2

Unter Linux ist sogar dokumentiert, dass dies passieren kann, wenn ich es lese.

Siehe diese Frage:

Benachrichtigung über Störungsbereitschaft für Select System call

    
Thomas 23.08.2009 11:23
quelle
0

Dies ist in einer Multithread-Umgebung möglich, in der zwei Threads vom Socket lesen. Ist das eine Multithread-Anwendung?

    
mikelong 26.05.2009 16:33
quelle
0

Wenn Sie keinen anderen syscall zwischen select () und recv () an diesem Socket aufrufen, gibt recv () niemals EAGAIN oder EWOULDBLOCK zurück.

Ich weiß nicht, was sie mit recv-timeout meinen, aber der POSIX-Standard erwähnt es hier nicht, so dass Sie recv () sicher anrufen können.

    
David Herrmann 26.05.2009 17:46
quelle
0

Obwohl meine Anwendung ein single-threaded ist, habe ich festgestellt, dass das beschriebene Verhalten in RHEL5 nicht ungewöhnlich ist. Sowohl mit TCP- als auch mit UDP-Sockets, die auf O_NONBLOCK (die einzige Socket-Option, die festgelegt wurde) festgelegt wurden. select () meldet, dass das Socket bereit ist, aber das folgende recv () gibt EAGAIN zurück.

    
mrvincenzo 27.05.2009 11:40
quelle

Tags und Links