Re: Socket send blocking problem

From: Alan J. McFarlane (alanjmcf_at_yahoo.com.INVALID)
Date: 05/13/04


Date: Thu, 13 May 2004 12:52:53 +0100

Andy <anonymous@discussions.microsoft.com> wrote:
> Hi,
> I've got an issue that I'm having some difficulty explaining.
> I'm running a TCP socket connection across a very slow network (low
> bandwidth).
> I am generating data faster than the transport layer can send it.

(If you mean in terms of bandwidth, then it obviously can't be done. You
can't send 10Mbps down a 56kbps line. So you must mean something else).

> The send buffer (as defined with SO_SNDBUF) gets filled, then data
> essentially stops getting transmitted.

How do you know this...

> Up until the point that the send buffer is filled, data is received
> at a reasonably steady rate at the other end.

Both sentences present things backwards. The network becomes congested,
sending thus slows down dramatically and *thus* the buffer fills.

> I'm intentionally sending a lot of small packets (nagles is
> disabled.. though I can see the issue either way).

Slow network, lots of small sends. Disable Nagle... GAME OVER. Your
network _will_ be in congestion collapse.

Also you are NOT "sending a lot of small packets", you are "doing lots of
small send()s". TCP will packetise the data in buffer as suits the
conditions. You have no direct control over what packets TCP will send
when. However, Nagel is required to make TCP behave well under these
conditions.

Are there any other applications running on this network? Any other users?
How happy are they when you are running this application? It is the network
that is suffering congestion, all other traffic will be affected...

Have you ensured that the bit rate you are putting into the network is less
that the network's capacity? How slow is the link? What is the RTT, when
quiescent and when under load? How often are you doing a send? What size
are they?

> It doesn't completely stop sending. It will start up again,
> generally with a larger packet size (even with nagles disabled) and

If there are multiple full packets' worth of data in the buffer, why would
TCP be crazy enough to send lots of small packets. Do some calculations:
look at Ethernet's interframe gap, look at other link layers. Look at the
CPU usage at the end-hosts and at routers, look at buffers usage on routers
etc etc. Work out for each the resources it takes to send a packet of
length 50 bytes and length 1500 bytes.

The overhead is mainly in the packet itself, not in its size. One should
never ever send even two small packets where one larger one can be sent, and
the benefit is obviously much larger with multiple small packets.

> start sending again for some short period of time. It's a bit
> cyclical. The xmit side just blocks until there is data space
> available to put into the send call.
> My question is why does the data stop getting to the other end just
> because my send buffer gets filled up?
> It somewhat is acting like it is in a retry delay of some sort.

Well typical behaviour would be that because one is sending many small
packets into the network, it 'collapses' into major congestion, TCP thus
backs-off a huge amount and then starts again very slowly. Then it gets to
the same condition as before and wheeee. Poor Mr Nagel, twenty years ago he
recognised, analysed and solved this problem and you turn his solution off.

> My second and probably more important question is there some way to
> peek at how much data is queued up in the kernel send buffer (size
> defined by SO_SNDBUF)?
> Is there a way to flush it?

What is your application, what is the data? Are you truly wanting to
discard the data in the send buffer?

Is the data flow bidirectional? How does your application protocol work?
Is it a request-response protocol.

> SO_SNDBUF set to zero won't cut it for me, as I don't want to wait
> for every transaction to to acked by the far end.

> I also have a lot of code written already to use the blocking send.
> I'd rather not have to use the sockets in a non-blocking mode if I
> can avoid it.
>
I'd doubt that that's the cause. More scalable IO models are required for
performance reasons on the end-host itself. There is no suggestion that
your box is overloaded...or is it?

-- 
Alan J. McFarlane
http://homepage.ntlworld.com/alanjmcf/
Please follow-up in the newsgroup for the benefit of all.


Relevant Pages

  • Re: General question about TCP and buffering in switch/router/modem
    ... ROUTER has a fixed 10mbps/half duplex interface for its wan port. ... Say the window size is 64k (roughly 50 packets). ... starts sending data after the TCP call has been established, ... ACK is received and the receiver's TCP buffer is not full. ...
    (comp.dcom.sys.cisco)
  • Re: Multicast Packet Delay
    ... the packets and stuffs them into the datalink layer. ... There's a buffer here of course, ... MTU of all network it traverses in order to avoid fragmenting ...
    (microsoft.public.win32.programmer.networks)
  • Re: UDP vs TCP
    ... TCP for instance will break up a large packet into smaller ... into the packets and then the receiving app would have to read ... Network Layer -> ethernet ... DOMAIN over port 53 ...
    (microsoft.public.vb.enterprise)
  • Re: 8Signs PC Firewall Problem
    ... > First a little understanding of my network setup... ... > If I turn 8 Signs PC Firewall Off, ... > the packets in realtime. ... > I was wondering if it's buffer problem, as in the buffer on the lan ...
    (comp.security.firewalls)
  • Re: Fundamentals question, is this how it works?
    ... processing packets after you are done with one. ... receving the buffer size each time. ... TCP is a stream-based protocol, which means that it ignores any attempt ... then the receiving side might get ...
    (microsoft.public.win32.programmer.networks)