• C

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.
chsalviaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.