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]
|
|
| 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
|
|
|
|
|