Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

socket select ()versus non-block recv

I've seen a few write-ups comparing select() with poll() or epoll(), and I've seen many guides discussing the actual usage of select() with multiple sockets.

However, what I can't seem to find is a comparison to a non-blocking recv() call without select(). In the event of only having 1 socket to read from and 1 socket to write to, is there any justification for using the select() call? The recv() method can be setup to not block and return an error (WSAEWOULDBLOCK) when there is no data available, so why bother to call select() when you have no other sockets to examine? Is the non-blocking recv() call much slower?

like image 236
Gren Meera Avatar asked Oct 03 '13 21:10

Gren Meera


People also ask

How can you tell if a socket is blocking or non-blocking?

From MSDN, the return value of connect(): On a blocking socket, the return value indicates success or failure of the connection attempt. With a nonblocking socket, the connection attempt cannot be completed immediately. In this case, connect will return SOCKET_ERROR , and WSAGetLastError() will return WSAEWOULDBLOCK.

What are the major differences between a blocking and non-blocking TCP sockets?

In blocking socket mode, a system call event halts the execution until an appropriate reply has been received. In non-blocking sockets, it continues to execute even if the system call has been invoked and deals with its reply appropriately later.

What is the difference between read () and recv ()?

The only difference between recv() and read(2) is the presence of flags. With a zero flags argument, recv() is generally equivalent to read(2) (but see NOTES).

How do you make a RECV non-blocking?

If data is not available and socket is in nonblocking mode, recv() returns a -1 and sets the error code to EWOULDBLOCK. See fcntl() — Control Open Socket Descriptors or ioctl() — Control Socket for a description of how to set nonblocking mode.


2 Answers

You wouldn't want a non-blocking call to recv without some other means for waiting for data on the socket as you poll infinitely eating up cpu time.

If you have no other sockets to examine and nothing else to do in the same thread, a blocking call to read is likely to be the most efficient solution. Although in such a situation, considering the efficiency of this is like to be premature optimisation.

These kinds of considerations only tend to come into play as the socket count increases.

Nonblocking calls are only faster in the context of handling multiple sockets on a single thread.

like image 77
goji Avatar answered Oct 20 '22 09:10

goji


If there is no data available, and you use non-blocking IO, recv() will return immediately. Then what should the program do ? You would need to call recv() in a loop until data becomes available - this just uses CPU for pretty much no reason.

Spinning on recv() and burning CPU in that manner is very undesirable; you'd rather want the process to wait until data becomes available and get woken up; that's what select()/poll() and similar does.

And, sleep() in the loop in order to not burn CPU is not a good solution either. You'd introduce high latency in the processing as the program will not be able to process data as soon as the data is available.

like image 30
nos Avatar answered Oct 20 '22 09:10

nos