Issue
I'm writing a server in Linux that will have to support simultaneous read/write operations from multiple clients. I want to use the select function to manage read/write availability.
What I don't understand is this: Suppose I want to wait until a socket has data available to be read. The documentation for select states that it blocks until there is data available to read, and that the read function will not block.
So if I'm using select and I know that the read function will not block, why would I need to set my sockets to non-blocking?
Solution
There might be cases when a socket is reported as ready but by the time you get to check it, it changes its state.
One of the good examples is accepting connections. When a new connection arrives, a listening socket is reported as ready for read. By the time you get to call accept, the connection might be closed by the other side before ever sending anything and before we called accept
. Of course, the handling of this case is OS-dependent, but it's possible that accept
will simply block until a new connection is established, which will cause our application to wait for indefinite amount of time preventing processing of other sockets. If your listening socket is in a non-blocking mode, this won't happen and you'll get EWOULDBLOCK
or some other error, but accept
will not block anyway.
Some kernels used to have (I hope it's fixed now) an interesting bug with UDP and select
. When a datagram arrives select
wakes up with the socket with datagram being marked as ready for read. The datagram checksum validation is postponed until a user code calls recvfrom
(or some other API capable of receiving UDP datagrams). When the code calls recvfrom
and the validating code detects a checksum mismatch, a datagram is simply dropped and recvfrom
ends up being blocked until a next datagram arrives. One of the patches fixing this problem (along with the problem description) can be found here.
Answered By - Maksim Skurydzin