I would like to know if the following scenario is real?!
For recv()
you would get EAGAIN
rather than EWOULDBLOCK
, and yes it is possible. Since you have just checked with select()
then one of two things happened:
select()
and recv()
. On Linux it's even documented that this can happen, as I read it.
See this question:
这是可能的,但只有在您有多个线程/进程试图从同一个套接字读取的情况下。
I am aware of an error in a popular desktop operating where O_NONBLOCK
TCP sockets, particularly those running over the loopback interface, can sometimes return EAGAIN
from recv()
after select()
reports the socket is ready for reading. In my case, this happens after the other side half-closes the sending stream.
For more details, see the source code for t_nx.ml
in the NX library of my OCaml Network Application Environment distribution. ( link )
Yes, it's real. Here's one way it can happen:
A future modification to the TCP protocol adds the ability for one side to "revoke" information it sent provided it hasn't been received yet by the other side's application layer. This feature is negotiated on the connection. The other side sends you some data, you get a select
hit. Before you can call recv
, the other side "revokes" the data using this new extension. Your read
gets a "would block" error because no data is available to be read.
The select
function is a status-reporting function that does not come with future guarantees. Assuming that a hit on select
now assures that a subsequent operation won't block is as invalid as using any other status-reporting function this way. It's as bad as using access
to try to ensure a subsequent operation won't fail due to incorrect permissions or using statfs
to try to ensure a subsequent write won't fail due to a full disk.
Though my application is a single-threaded one, I noticed that the described behavior is not uncommon in RHEL5. Both with TCP and UDP sockets that were set to O_NONBLOCK (the only socket option that is set). select() reports that the socket is ready but the following recv() returns EAGAIN.
It is possible in a multithreaded environment where two threads are reading from the socket. Is this a multithreaded application?
If you do not call any other syscall between select() and recv() on this socket, then recv() will never return EAGAIN or EWOULDBLOCK.
I don't know what they mean with recv-timeout, however, the POSIX standard does not mention it here so you can be safe calling recv().
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.