sockets non blocking mode timeout

What is the meaning of timeout in non blocking mode. If for instance it can not read data in that time it will generate an error after time elapsed? But not before? What time for that I select on what criterias?

What if nothing is to be read? EWOULDBLOCK will be generated before timeout or at the same time timeout expired?
On this site it stated an immediate return of EWOULDBLOCK?
https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.1.0/com.ibm.zos.v2r1.hala001/orgblockasyn.htm
What if I am having while loop to wait something will have pending data to be read? Something like:

ioctlsocket(ListenSocket, FIONREAD, &bufferdata);

while (bafferdata != 0)
ReceivedDataLen = recvfrom(ListenSocket, ReceiveBuffer, BUFFERSZ, 0, (struct sockaddr *)&Server, &ServerLen);

How to stop generated EWOULDBLOCK?


Last edited on
In my scenario I select for network events, and if there is no input packet, no recv is called, and when it is called, it should not return an error, so if it did error, I would just drop the client (because why not), then after selecting, I loop through my clients to see if any of them have timed out, and if so, I close the socket.

Not an expert, but that's how it works for me. I use winsock, and you use bsd sockets, but it should be pretty equal.
No that is windows as well. Here is my code to be tested..

FD_SET ReadSet;
FD_ZERO(&ReadSet);
FD_SET(ListenSocket, &ReadSet);

struct timeval TimeOut;
TimeOut.tv_usec = 500000; /* 0.1sec timeout */

RECEIVED = select(0, &ReadSet, NULL, NULL, &TimeOut);
while (RECEIVED > 0)
{
receivedBytes = recvfrom(ListenSocket, ReceiveBuffer, BUFFERSZ, 0, 0, 0);
//if (receivedBytes == SOCKET_ERROR) {
// wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
//}
int ierr = WSAGetLastError();
if (ierr == WSAEWOULDBLOCK)
{ // currently no data available
Sleep(50); // wait and try again
continue;
}


I read docs from:

https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/nf-winsock2-select

it says:

int WSAAPI select(
int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
const timeval *timeout
);

it is interesting the following: "exceptfds
An optional pointer to a set of sockets to be checked for errors."

we have: "Return Value: The select function returns the total number of socket
handles that are ready and contained in the fd_set structures, zero if the time limit expired, or SOCKET_ERROR
if an error occurred. If the return value is SOCKET_ERROR, WSAGetLastError can be used to
retrieve a specific error code". Ok I know that I have ony one socket that is ready (NOT that data is available).
I have impression that documentation suggests that is to notify that data is available for reading?????? Again the return
value will inform us that that it is zero when time limit expires! The errors in documentation are more or less in wnsock setup and do not
have anything with to do with data to be read. Or I am missing something?
That code isn't quite right.

select() returns the number of sockets that generated matching events. For each socket, you still need to check if it's in the required state.

For example, if you're listening for sockets that are available to be read, you have to check each socket, otherwise it will block (for blocking sockets), or fail (for non-blocking sockets).

The idea is processing is often faster than I/O. So, there's no point in waiting around for I/O to complete if you have other things to do. So you issue your command, and react to a completion event later on, and in the mean time, you can do something else.

The original method event loop was select(). It takes an array of file descriptors and/or sockets. It uses an O(n) complexity algorithm to do the wait. And so there are improvements to this basic method over time.

As it happens, if you're using an asynchronous method to check it you can read/write a socket, you don't need to make it asynchronous. Typically, you only need an asynchronous socket if you're working within a non-cooperative message processing system, like the Windows message loop, as you'll never try read a socket that's not available to read, and similarly for write.
From:
https://www.mkssoftware.com/docs/man3/recvfrom.3.asp

"The recvfrom() system call receives a message from a socket and capture the
address from which the data was sent. Unlike the recv() call, which can only be used on a
connected stream socket or bound datagram socket, recvfrom() can be used to receive data on a
socket whether or not it is connected. If no messages are available at the socket, the recvfrom() call
waits for a message to arrive unless the socket is nonblocking. If a socket is nonblocking, -1 is
returned and the external variable errno is set to EWOULDBLOCK. select() can be used
to wait for incoming messages."

That is problem in my code. My socket is non blocking. Then we have to put what I did

while (RECEIVED > 0)
{
receivedBytes = recvfrom(ListenSocket, ReceiveBuffer, BUFFERSZ, 0, 0, 0);
ierr = WSAGetLastError();
if (ierr == WSAEWOULDBLOCK)
{ // currently no data available
Sleep(50); // wait and try again
continue;
}


If that system is non blocking then with sleep() it waits .
what I want is to:

1. Find the way which will inform me when data is available on listen socket to be read
2. Handle error wsaewouldBlock without using Sleep()
Last edited on
Overall, you need to look at examples on how how to use the library, when you want to receive in a loop, you have to loop select itself. Select will return SOCKET_ERRROR, and in that case you call WSAGetLastError, and also check if it returns 0, otherwise if you get an error with recvfrom, that is unexpected. The timeout that is inside of the select is blocking, you just wait for like 100 micro seconds (which is insignificant), then write your own hand written timeout system.
If you're waiting, why are you using non-blocking sockets in the first place?
Topic archived. No new replies allowed.