• C

Socket Programming in C - Problem with the recv() function

I am writing a little program to learn about socket programming.  So far, it listens on a specific port, and I am able to telnet in and send a message.  It then recieves the message and displays it on the screen.  

My problem is this.  I believe I have to call recv in a while loop, as the entire message (if it is long) may not be recieved all at once.

The code below shows how I am handling the recieving of a message.  The problem is that recv() blocks until.... ?  I get stuck in the loop until I send over a bunch of characters (around 150).  How can I make sure that I get the entire message (if its big), but dont get blocked if the msg is small?

Thanks,
Jonathan
int readData(int openSocket, char *buf, int bufsize)
{
  int bcount;  //total num bytes read
  int br;      //bytes read in this pass
  bcount= 0;
  br= 0;
  br = recv(openSocket, buf, bufsize-bcount,0);
  bcount += br;
  while (br > 0) //if 0 is returned it means the msg is complete?
  {            
    if ((br= recv(openSocket,buf,bufsize-bcount, 0)) > 0) {
      bcount += br;                
      buf += br;
    }
    else if (br < 0)     
  return(-1);
  }
return(bcount);
}

Open in new window

jonathanjeffreyAsked:
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.

jax79sgCommented:
First, you have to recognize that recv() means receiving the information from its input buffer(on a lower level). In fact, to the method, its only a bunch of data which it doesn't understand.

Now, you can design the your message with a simple structure.
Say, at the start of the message, place a unqiue set of characters which you know will never appear in the actual message transfer. Same for end of your message.

<get the entire message (if its big)>
Now you can code it such that so long as you do not receive the unique 'END OF MESSAGE' characters, you will continue with recv(). In other words, you expect more data to be recieved from your sending computer.So you sit and wait. If 'END OF MESSAGE' characters are already received, you will get yourself out of the loop.

<but dont get blocked if the msg is small>
The implementation above will take care of this as well.
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
evilrixSenior Software Engineer (Avast)Commented:
Have a look at the select() function, which checks to see if there is data to be read before you call the read() function.
http://msdn2.microsoft.com/en-us/library/ms740141(VS.85).aspx

"The parameter readfds identifies the sockets that are to be checked for readability... readability means that queued data is available for reading such that a call to recv, WSARecv, WSARecvFrom, or recvfrom is guaranteed not to block."
0
jonathanjeffreyAuthor Commented:
jax79sg:  Eventually I want to have this function as a proxy server, and so I will be handling requests from my browser.  The problem is that the request I get from my browser does not always end with a specific sequence of characters.  

evilrix: I'm not worried about blocking while waiting for a message to be sent.  I just want to be sure that I get the whole message (Maybe if its a really big message it will be split up into several smaller messages, and recv() will return without having read everything??)
0
jax79sgCommented:
well, if you are going to work on the browser messages on your own, you will need to adhere to their message standards. Some protocols uses a end message character, others places a message length in the message header. You will need to read that up. The following is a link to get u started.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4

PS: Do consider spending 1/2 hr and look for ready made C packages that might have done this portion of work for you.
0
jonathanjeffreyAuthor Commented:
Ok, thank you guys.  I ended up using the sentinal value for the problem.  The requests I get from the webrowser always end in /r/n/r/n, so I am able to use that to terminate the recv() while loop.

0
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.