strange sockets

Sion Arrowsmith siona at chiark.greenend.org.uk
Fri Nov 4 12:01:16 EST 2005


In article <dkfqhb$l1l$1 at opal.futuro.pl>, Skink  <spam at me.please> wrote:
>% python client.py client.py client.py client.py server.py server.py
>init 0.00066089630127
>client.py 0.000954866409302
>client.py 0.0408389568329
>client.py 0.0409188270569
>server.py 0.0409059524536
>server.py 0.0409259796143
>
>what's wrong here?

That smells of a Nagle/delayed ACK problem to me (see, for instance,
http://www.port80software.com/200ok/archive/2005/01/31/317.aspx). 40ms
is the default delayed ACK timeout on Linux, IIRC (pretty much
everything else uses 200ms). I *think* what's happening from the
server's point of view is:

receive request 1
send length (first undersized packet is sent immediately by Nagle)
(client delays ack #1)
send data (larger than 1 packet, send immediately)
(client delays acks #2--#n)
receive request 2 with ack #1
buffer sending length (undersized packet, not received last ack)
-> 40ms passes <-
(client timesout delayed acks and sends)
send length
send data (as before)

although why the undersized packet at the end of the first chunk of
data isn't buffered, I don't know.

Solutions: either change

>        conn.sendall(struct.pack("!i", len(data)))
>        conn.sendall(data)

to

conn.sendall(struct.pack("!i", len(data)) + data)

or after creating conn

conn.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)

to disable Nagle.

-- 
\S -- siona at chiark.greenend.org.uk -- http://www.chaos.org.uk/~sion/
  ___  |  "Frankly I have no feelings towards penguins one way or the other"
  \X/  |    -- Arthur C. Clarke
   her nu becomeþ se bera eadward ofdun hlæddre heafdes bæce bump bump bump



More information about the Python-list mailing list