Why is a non-blocking TCP connect() occasionally so slow on Linux?

Posted by pts on Stack Overflow See other posts from Stack Overflow or by pts
Published on 2010-04-25T15:29:32Z Indexed on 2010/04/25 15:33 UTC
Read the original article Hit count: 204

Filed under:
|
|
|

I was trying to measure the speed of a TCP server I'm writing, and I've noticed that there might be a fundamental problem of measuring the speed of the connect() calls: if I connect in a non-blocking way, connect() operations become very slow after a few seconds. Here is the example code in Python:

#! /usr/bin/python2.4
import errno
import os
import select
import socket
import sys

def NonBlockingConnect(sock, addr):
  while True:
    try:
      return sock.connect(addr)
    except socket.error, e:
      if e.args[0] not in (errno.EINPROGRESS, errno.EALREADY):
        raise
      os.write(2, '^')
      if not select.select((), (sock,), (), 0.5)[1]:
        os.write(2, 'P')

def InfiniteClient(addr):
  while True:
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
    sock.setblocking(0)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # sock.connect(addr)
    NonBlockingConnect(sock, addr)
    sock.close()
    os.write(2, '.')

def InfiniteServer(server_socket):
  while True:
    sock, addr = server_socket.accept()
    sock.close()

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('127.0.0.1', 45454))
server_socket.listen(128)

if os.fork():  # Parent.
  InfiniteServer(server_socket)
else:
  addr = server_socket.getsockname()
  server_socket.close()
  InfiniteClient(addr)

With NonBlockingConnect, most connect() operations are fast, but in every few seconds there happens to be one connect() operation which takes at least 2 seconds (as indicated by 5 consecutive P letters on the output). By using sock.connect instead of NonBlockingConnect all connect operations seem to be fast.

How is it possible to get rid of these slow connect()s?

I'm running Ubuntu Karmic desktop with the standard PAE kernel:

Linux narancs 2.6.31-20-generic-pae #57-Ubuntu SMP Mon Feb 8 10:23:59 UTC 2010 i686 GNU/Linux

© Stack Overflow or respective owner

Related posts about linux

Related posts about socket