Re: Network buffering question



[Oops, fingers slipped. I have canceled my previous reply; please ignore if
you can see it.]

"Till Crueger" <TillFC@xxxxxxx> wrote in message
news:pan.2006.08.28.22.18.25.590148@xxxxxxxxxx
[snip]
I am working on some network code right now. For help I am using "Beej's
Guide to Network Programming". Now I stumbled upon the chapter about data
encapsulation. I get the point that you should send across the Network
some information about how much data you have been sending, so you can
reconstruct the packets correctely. So far I think I got everything.

However then he says that you need to make your buffer twice as large as a
single packet, because you might actually read past the packet you are
trying to handle at the moment. Since you can tell recv() how much you
want to recieve couldn't you just make sure this wont ever happen?

I cannot see a valid reason for the buffer being "twice as large as a single
packet". However, an "oversized" buffer is a good thing up to a point.

You can make sure you don't read past a message if you know how long the
message is in advance, but that is often not the case. Many protocols use a
delimiter to separate messages, for instance the sequence CR, LF.

recv() is usually a relatively expensive function call, so it can make a
difference to performance if you reduce the number of calls you make. That
means it is a good idea to pass a reasonable buffer size to recv(), then
extract messages from the buffer by parsing it.

I disagree with Scott's suggestion of a large circular buffer. It is
wasteful of memory and a long time ago I found it to have marginally lower
performance than a simpler approach, which goes something like this:

int complete_message(const char *p, size_t n);
/* returns non-zero if the message starting at p is at most n bytes,
* which means it is all in the buffer.
*/
size_t length_of_message(const char *p);
/* returns length of message starting at p. */

leftover = 0;
for (;;) {
bytes = leftover + recv(s, buf + leftover, buf_size - leftover, 0);
start_of_msg = buf;
while (bytes > 0 && complete_message(start_of_msg, bytes)) {
process_message(start_of_msg);
start_of_msg += length_of_msg(start_of_msg);
bytes -= length_of_msg(start_of_msg);
}
leftover = bytes;
memcpy(buf, start_of_msg, leftover);
}

In practice, leftover is rarely non-zero, so the memcpy() is usually a
no-op.

Alex


.



Relevant Pages

  • Re: Network buffering question
    ... Guide to Network Programming". ... single packet, because you might actually read past the packet you are ... want to recieve couldn't you just make sure this wont ever happen? ... I cannot see a valid reason for the buffer being "twice as large as a single ...
    (comp.programming)
  • Re: Interesting TCP behaviour with large sends/small buffers
    ... My current workaround is simply setting the send buffer to a larger ... The server, upon connection, sends a configurable number of bytes to ... packet before sending the next packet. ... ACK, according to the delayed ACK algorithm - 50KB bytes means 34 MSS- ...
    (microsoft.public.win32.programmer.networks)
  • Re: Interesting TCP behaviour with large sends/small buffers
    ... The server, upon connection, sends a configurable number of bytes to ... I set the client's receive buffer size to 1MBps, ... packet before sending the next packet. ... ACK, according to the delayed ACK algorithm - 50KB bytes means 34 MSS- ...
    (microsoft.public.win32.programmer.networks)
  • Re: Fundamentals question, is this how it works?
    ... You maintain a buffer for the last incomplete packet. ... receiving that many bytes i then break and wait for the next set of data ... With a tcp stream socket what happens when it is reading say 4000bytes ...
    (microsoft.public.win32.programmer.networks)
  • Re: Design of a Router
    ... packet forward it and than close the port and move to the next and so ... would ideally like the router as small and as fast as possible. ... size of your buffer (just keep in mind that if you have 4 ports than ...
    (comp.lang.verilog)