Re: recv() sends extra garbage bytes
- From: chsalvia@xxxxxxxxx
- Date: 27 Mar 2007 00:47:48 -0700
You are not guaranteed to have received 4 bytes of data (since new_sock
is a SOCK_STREAM socket).
}
uint32_t rem_bytes = recv_size - sizeof(uint32_t);
If you did not receive 4 bytes, you just hosed yourself.
Good point. I overlooked the possibility that the initial recv might
get less than 4 bytes. I changed it so that the initial receive loops
until it gets 4 bytes.
I'd be worried that rem_bytes may be larger than buffer can hold, first
because you don't pass the size of buffer to compare it against, and
second because of the bug above.
As you noticed above, I didn't copy and paste the exact code. The
reason I didn't was because my actual code uses a customized C++
buffer class that handles memory allocation. I tried to simplify my
code for the purpose of posting it here - perhaps that was a bad
idea. The loop is actually like this:
do {
switch (buffer.recv(new_socket, recv_size)) {
case -1: return SOCKET_ERR;
case 0: return CLOSE_SOCKET;
default: break;
}
} while (buffer.used_bytes < recv_size);
With buffer.recv() defined as:
inline int recv(int m_sock, uint32_t maxrecv, int flags = 0) {
if (used_bytes + maxrecv > size) realloc_buffer(used_bytes +
maxrecv);
int status = ::recv(m_sock, (byte*) data + used_bytes, maxrecv,
flags);
if (status > 0) used_bytes += status;
return status;
}
And of course, the member variable used_bytes keeps track of the
buffer length, and size keeps track of allocated space.
You have at least 2 bugs. You are not checking that you received 4
bytes initially, and you are not checking that the length of the
message will fit in your buffer. Otherwise there might be a bug on
the sender's side.
Thanks for pointing out that out. Before you said that "what is
actually sent" is loosely defined. Is there any possible way that a
server could recv() *more* data than a client sends? In my case, I
notice that every now and then, I'll receive an additional 1000 bytes
or so of garbage data on the tail end of the message. (Typical
message length is approx 300K.)
This problem doesn't seem like it could be related to the first bug
you pointed out, because even if I received less than the full 4 bytes
and then erroneously assigned the incomplete value to recv_size, this
would either result in me receiving *less* bytes than I expected,
(because a 4 byte integer containing a value like 300000 for example
would be if only 1 byte or 2 bytes were received), OR, if recv_size
contained some initial garbage value in it, it would be set to some
arbitrary high value, in which case I would recv() the full amount
anyway. This doesn't explain why I'd receive an additional ~1000
bytes of garbage data.
Is there any reason why recv() might get more data than was actually
sent by send()?
.
- Follow-Ups:
- Re: recv() sends extra garbage bytes
- From: David Schwartz
- Re: recv() sends extra garbage bytes
- From: Frank Cusack
- Re: recv() sends extra garbage bytes
- References:
- recv() sends extra garbage bytes
- From: chsalvia
- Re: recv() sends extra garbage bytes
- From: Frank Cusack
- recv() sends extra garbage bytes
- Prev by Date: Re: recv() sends extra garbage bytes
- Next by Date: Re: recv() sends extra garbage bytes
- Previous by thread: Re: recv() sends extra garbage bytes
- Next by thread: Re: recv() sends extra garbage bytes
- Index(es):
Relevant Pages
|
|