Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to know the size of buffer beforehand in recv() function?

Status
Not open for further replies.

sulacco

Technical User
Nov 8, 2002
74
RU
I'm using recv(...) function to get messages from pop server.
How do I know how much buffer I need to use in recv() beforehand?
 
Well typically there should be some predetermined maximum packet size. If you don't know what that is, you can use the following to see if the socket is waiting to recieve data:

fd_set conn;
FD_ZERO(&conn);
FD_SET(ListeningSocket, &conn);
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
int s = select(0, &conn, NULL, NULL, &timeout);

If s > 0 and not equal to INVALID_SOCKET, it is ready to recieve data. Just use this in conjunction with a while loop and recv with a buffer of some size (say 256 or so) to get all the data that is waiting.
 
Well, thanks, but what kind of while I should have?
How it looks like?
 
Size of your buffer you specify by yourself in third parameter of recv(). You should call recv() repeatedly until no more bytes are received.
Code:
do
{
   received=recv(your_socket, your_buffer, buf_size, 0);
   if(received)
   {
      ...
   }
} while(received);
 
recv() could receive not only amount of bytes, but SOCKET_ERROR as well. This return value should be also checked.
 
mingis, the problem with that is recv is blocking, so it will wait for additional data without returning if there is none available. This is why I suggest using select as above, which is not blocking.
 
timmay3141 is absolutely right. I've made the while loop like mingis said
and while it can receive all data all right it hanged in one of the
cycles. But nevertheless, thanks, guys. mingis helped me too to move to
the problem closer.
 
Do I have something like this?
...
FD_ZERO(&conn);
FD_SET(ServerSock, &conn);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
BYTE *sBuf[256];

while(s=select(0, &conn, NULL, NULL, &timeout)){
iLength = recv(ServerSock, (LPSTR)sBuf, sizeof(sBuf), 0);

}
 
Probably one should use only protocoll-formatted messages then - receive only message header first, and after that receive message of exact length as stated in the header.
 
Sorry, "should" must be read as "could". The right ansver is about select(), of course.

 
Well you'd have to do more in the while loop than just recieve the buffer (handle it however you need to), but I think you also need to use FD_ZERO and FD_SET every time before you call select, so those need to be in the while loop as well. sBuf should be a char (same as BYTE) array rather than a BYTE* array, because an array of 256 pointers to bytes would not be especially useful. Then you would call recv like this:

recv(ServerSock, sBuf, 256, 0);
 
Yep there's typo I mean:
BYTE sBuf[256];
And why should I need to "...FD_ZERO and FD_SET every time before you call select..." ?


 
I believe that select modifies the content of the fd_set (in this case conn), so you need to restore the old values for it to work properly.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top