When will the send buffer be full??

Started by
5 comments, last by hplus0603 13 years, 4 months ago
hi I just want to know in what occasion the send buffer be full. anyone ever experienced this?? and what action should be taken accordingly?? do I wait(for some time)and keep sending or return immediately and show error message?? and then what? close connection? exit the app?
Advertisement
Are you referring to the socket send() function?


By default it will block. For most uses of sockets blocking is the best behavior.

If it doesn't block, it will buffer whatever it can and return that length.

The send() function returns -1 on error, or the number of bytes sent (which may be less than those you specified).


All this and more (such as the error codes and conditions) can be found in your API/SDK documentation.
The semantics of send() is that, if it can transfer at least one byte into the buffer, it will transfer as much as possible, and then return (possibly not transferring everything). If the buffer is entirely full, send() will block until it can transfer at least something, unless the socket is in non-blocking mode, in which case it will return a WOULDBLOCK error.

select() ties into this, by returning a socket as writable if there is at least some space for send() to write into.

The default buffer for a socket that you just opened is dependent on your OS. Perhaps 16 kB, or thereabouts. You can change it by calling ioctl() / ioctlsocket(). For TCP, you want to do this before you call connect() (or listen()), so that TCP window scaling can be calculated.

Generally, I have an application-level buffer, where outgoing packets are queued. When select() then says there is space to write, I send whatever I can from the queue. If the queue is ever greater than X, where I determine X based on the application's needs, then I draw the conclusion that the client is hopelessly slow or behind, and close the socket/disconnect the client. I do this so that I don't have to call send() from within application code; rather, just link the packet into an application-layer queue.
enum Bool { True, False, FileNotFound };
ok, so what cause this is a heavy packet loss?? from what I know, pakets are kept by TCP until it gets acked. if not, it will resend until it gets one.
is that right?? hmm and the buffer is supplied per socket. thx for the info hplus n frob, btw 16kb is a lot of buffer(for games)isnt it??
16 kB is way too much, or way too little, or just the right amount, depending on what your application needs. Hence, it's a good idea to tweak it to what your application actually expects.

Backing up and filling the send buffer can happen in many ways. Packet loss is one. Lack of bandwidth is another. Slow receiving on the other end, so the receive buffer fills up is a third.
enum Bool { True, False, FileNotFound };
well those 3 factors are tightly correlated! ok thx hplus 4 the info. by the way the default buffer size is 8k. well I guess I'll just disconnect those failed in send(). pretty simple, anyway, does the Nagle affect it too??
Nagle will try to coalesce writes less than the size of an MTU. The MTU is typically in the 1.5 kB range; as soon as you fill one MTU, Nagle will not delay any data, so it shouldn't affect the backing-up of the buffer.

Of course, if you try to send large packets (many packets of size 1k, or a single packet greater than 8k) you will end up immediately blocking. Hence, why you should tweak the default buffer size to match whatever your application really needs.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement