• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 7936
  • Last Modified:

Recv timeout on non-blocking socket

I'm trying to figure out how to avoid recv() calls that hang forever by using using a non-blocking socket along with the select() function.  This seems to be the standard way to avoid recv() calls that hang forever.

I'm having difficulty getting this to work however.  It seems to work sometimes, but occasionally the recv() call hangs.  Additionally, I think the loop I'm using is not doing something right, because it slows down the system indicating it is using a lot of CPU cycles.

Here is the recv() function I used:

      bool recv_non_block(char* buf)
      {      
            int status;
            do {
                  if ((status = recv(m_sock, buf, RECV_BUF_SIZE, 0)) == -1) {
                        if (errno == EWOULDBLOCK || errno == EAGAIN) {
                              if (Select()) continue;
                        }
                        else return false;
                  }
            } while (status != 0);
            return true;
      }

Note: The Select() function is simply a convenient wrapper for the select() function call.

Is the above loop a correct way to receive on a non-blocking socket?  Note also that since this can be used on an Internet website, I do not necessarily know the size of the data I am receiving, and therefore I need to rely on recv() returning 0 in order to end the loop.
0
chsalvia
Asked:
chsalvia
1 Solution
 
ethan_mmgCommented:
Why not use recv in its own thread? It can block there while waiting for input. When data arrives, it can send a message to your main thread.
0
 
chsalviaAuthor Commented:
That's one possible solution.  But in a multi-threaded environment that would require twice as many threads.

I have discovered that creating a truly robust recv timeout is actually one of the most difficult things to program.  Every approach I try has some flaw in it.  For example, I initially tried using blocking sockets, and setting the SO_RCVTIMEO property.  This seemed to work well, but when I used a lot of concurrent threads, various recv calls would still mysteriously hang.  

Another option was to simply use SIGALRM to time out.  But this doesn't work well in a multi-threaded environment either.

So finally I tried non-blocking sockets.  This way I have more control over the recv() call.  Again, this seems to work fine initially.  But when there are a lot of concurrent threads, many of them still hang on recv().
0
 
Computer101Commented:
PAQed with points refunded (500)

Computer101
EE Admin
0

Featured Post

Get Certified for a Job in Cybersecurity

Want an exciting career in an emerging field? Earn your MS in Cybersecurity and get certified in ethical hacking or computer forensic investigation. WGU’s MSCSIA degree program was designed to meet the most recent U.S. Department of Homeland Security (DHS) and NSA guidelines.  

Tackle projects and never again get stuck behind a technical roadblock.
Join Now