For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > September 2006 > recv "n" bytes









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author recv "n" bytes
axsmth@gmail.com

2006-09-18, 10:01 pm

Hi,
What is the best strategy to read in "n" bytes using a receive?
This is what I have thought of --
The first byte of the data I send is the total size of the buffer.
So First I use MSG_PEEK in recv to read the first byte.
Then I loop the recv call until I read all the bytes.
However, this is causing problems.
Is there an easier way?
Thanks,
Max

Nils O. Selåsdal

2006-09-19, 4:00 am

axsmth@gmail.com wrote:
> Hi,
> What is the best strategy to read in "n" bytes using a receive?
> This is what I have thought of --
> The first byte of the data I send is the total size of the buffer.
> So First I use MSG_PEEK in recv to read the first byte.
> Then I loop the recv call until I read all the bytes.
> However, this is causing problems.

Why is that causing problems ?

See the MSG_WAITALL flag to recv as well, btw.

> Is there an easier way?

Not really, but there are "harder" and more efficient ways.
(grab a big chunk at a time, parse it - keep track of lengths,
partial and multiple messages you fetch with one call)

> Thanks,
> Max
>

axsmth@gmail.com

2006-09-19, 4:00 am

Hi,
This is my function -

#define SIZE 8000
char buf[SIZE];

char *storbuf;


//bufsize is read from socket using MSG_PEEK
storbuf = (char *)(malloc(sizeof(bufsize)));

err = recvall(sockfd,buf,storbuf,&bufsize);

int recvall(int s,char *buf,char *storbuf,int *len)
{
int total = 0; //total bytes we have received
int bytesleft = *len; //total bytes left to receive
int n;

while(total < *len)
{
n = recv(s, buf ,SIZE-1,0);
memcpy(storbuf+total,buf,n);
if (n== -1)
{
perror("Receiveall");
exit(1);
}
printf("\nReceived so far:%d",n);
total+=n;
bytesleft -= n;
}
*len = total;

return n==-1?-1:0;
}

However this code read more than *len and on return I sometimes get the
error : cannot allocate memory.
Is theree something I am overlooking?
Yes, i am looking into MSG_WAITALL.. thanks.. Will it work for huge
buffers like say 1 million bytes?
Thanks,
Max

Nils O. Selåsdal

2006-09-19, 4:00 am

axsmth@gmail.com wrote:
> Hi,
> This is my function -
>
> #define SIZE 8000
> char buf[SIZE];
>
> char *storbuf;
>
>
> //bufsize is read from socket using MSG_PEEK
> storbuf = (char *)(malloc(sizeof(bufsize)));
>
> err = recvall(sockfd,buf,storbuf,&bufsize);

Are you sure 'bufsize' is read/converted correctly ?

> int recvall(int s,char *buf,char *storbuf,int *len)
> {

Validating that the size is sane would be a good idea too

> int total = 0; //total bytes we have received
> int bytesleft = *len; //total bytes left to receive
> int n;
>
> while(total < *len)
> {
> n = recv(s, buf ,SIZE-1,0);

here you read SIZE -1 everytime. You might risk reading the last part
of the current "message" and e.g. half of the next message, getting you
out of sync, unless you only read one message per connection.


> memcpy(storbuf+total,buf,n);
> if (n== -1)

handle n == 0 too, it means the peer closed.

> {
> perror("Receiveall");
> exit(1);
> }
> printf("\nReceived so far:%d",n);
> total+=n;
> bytesleft -= n;
> }
> *len = total;
>
> return n==-1?-1:0;
> }
>
> However this code read more than *len and on return I sometimes get the
> error : cannot allocate memory.
> Is theree something I am overlooking?
> Yes, i am looking into MSG_WAITALL.. thanks.. Will it work for huge
> buffers like say 1 million bytes?

If the rest of your system handles that, sure..
btw, look at
http://www.cis.temple.edu/~ingargio...12e/lib/readn.c
from the recommended Unix Network Programming book :)
Frank Cusack

2006-09-19, 7:02 pm

On 18 Sep 2006 21:44:54 -0700 axsmth@gmail.com wrote:
> Hi,
> This is my function -
>
> #define SIZE 8000
> char buf[SIZE];
>
> char *storbuf;
>
>
> //bufsize is read from socket using MSG_PEEK
> storbuf = (char *)(malloc(sizeof(bufsize)));


1) don't cast the return value of malloc()
2) you don't check the return value
3) is this legal C?

> err = recvall(sockfd,buf,storbuf,&bufsize);
>
> int recvall(int s,char *buf,char *storbuf,int *len)
> {
> int total = 0; //total bytes we have received
> int bytesleft = *len; //total bytes left to receive
> int n;
>
> while(total < *len)
> {
> n = recv(s, buf ,SIZE-1,0);
> memcpy(storbuf+total,buf,n);


This is a bug. ALWAYS check the return value. If n == -1 here, you
will segfault.

-frank
Barry Margolin

2006-09-20, 4:00 am

In article <450f7a4f$1@news.broadpark.no>,
"Nils O. Selåsdal" <NOS@Utel.no> wrote:

> axsmth@gmail.com wrote:
> Are you sure 'bufsize' is read/converted correctly ?
>
> Validating that the size is sane would be a good idea too
>
> here you read SIZE -1 everytime. You might risk reading the last part
> of the current "message" and e.g. half of the next message, getting you
> out of sync, unless you only read one message per connection.


In fact, I was trying to figure out what his "bytesleft" variable was
for -- he initializes it and decrements it, but never uses it. It turns
out that this is what he should be using in the recv() call instead of
SIZE-1. Also, the while test can be changed to

while (bytesleft > 0)

which I find a little clearer (and it saves an indirection).
[color=darkred]

Why do this copy? Why not just pass storbuf+total to recv(), so that it
will write directly into the caller's buffer?

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
David Schwartz

2006-09-20, 7:01 pm


axsmth@gmail.com wrote:

> n = recv(s, buf ,SIZE-1,0);
> memcpy(storbuf+total,buf,n);


Why receive it into one place just to copy it into someplace else? Why
not receive it where you wanted it in the first place? That would allow
you to get rid of the second buffer entirely.

DS

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com