| Dale Hagglund 2005-12-19, 6:02 pm |
| >>>>> "Steven" == Steven <stevong@gmail.com> writes:
Steven> I'm puzzled. How do you usually define the length to be
Steven> given for recv()?
In all of the below, I'm going to assume you want to read from a TCP
socket. A number of related factors come into play:
(a) A TCP is socket is just a sequence of bytes. That means
that, on the receiving end, you have no way of knowing
whether or not the sender did two 100 byte writes or a
single 200 byte writes. Ie, TCP sockets themselves
provide no help in recovering message boundaries that are
important to your application.
(b) The third parameter of recv() is the maximum amount of
data to pull from the socket, and has nothing directly to
do with the application message to receive.
(c) recv() can return less data than requested. Ie, you might
ask for 100 bytes and get only 50 back. The remaining 50
are still there (barring various errors) and you have to
call recv() again to get them.
Steven> Since you do not know what is the length of the buffer you
Steven> are going to receive?
You have to figure out a way to know how much data to expect, since
TCP sockets give you no help themselves. (This is called a "framing
protocol".) A typical way is for the sender to write a fixed-length
header which contains the length of the following data. Then, your
message handling function looks a bit like this:
length = read_length_from_socket(s);
handle_next_message(s, length);
Point (c) above is usually more annoying. Just because you know that
you have, say, 1000 bytes to receive, doesn't mean that
struct buf[1000]
recv(s, buf, sizeof buf);
actually gets you all the data. It gets you *no more than* 1000
bytes, and returns how many it actually got. Instead, you have to
write it as
struct buf[1000];
char *b = buf;
int remaining = sizeof(buf);
int n;
while (remaining > 0) {
n = recv(s, b, remaining);
b += n;
remaining -= n;
}
At the end of this loop, barring early end of file and other errors
which have been totally ignored, you've pulled 1000 bytes out of the
socket, whether or not recv() returned it all at once or one byte at a
time.
Dale.
|