Archimaredes
Archimaredes

Reputation: 1427

Python 3.2.3: Socket takes longer to timeout than it should?

I'm using Python 3.2.3 on Windows 7, and one piece of code I have connects to a server with a blocking socket, with a user-specified timeout value. The code is simply:

testconn = socket.create_connection((host, port), timeout)

The code works fine, apart from the odd fact that timing out seems to take longer than it should on invalid requests. I tried connecting to www.google.com:59855 deliberately (random port should mean it should try connecting until it reaches the timeout), with a timeout of 5 seconds, but it seemed to take 15 seconds at least to timeout.

Are there any possible reasons for this, and/or any fixes? (It's not a huge problem if it's not fixable, but a solution would be appreciated nevertheless.) Thanks in advance.

Upvotes: 2

Views: 994

Answers (1)

Neal
Neal

Reputation: 6982

This isn't an issue specific to Python 3 or Windows. Take a look at the docs for create_connection(): http://docs.python.org/library/socket.html#socket.create_connection

The important snippet is:

if host is a non-numeric hostname, it will try to resolve it for both AF_INET and AF_INET6, and then try to connect to all possible addresses in turn until a connection succeeds.

It resolves the name using socket.getaddrinfo. If you run

socket.getaddrinfo('google.com', 59855, 0, socket.SOCK_STREAM)

You'll probably get a few results returned. When you call socket.create_connection, it will iterate over all of those results, each waiting for timeout seconds until it fails. Because it waits timeout seconds for EACH result, the total time is obviously going to be greater than timeout.

If you call create_connection with an IP address rather than host name, e.g.

testconn = socket.create_connection(('74.125.226.201', 59855), timeout=5)

you should get your 5 second timeout.

And if you're really curious, take a look at the source for create_connection. It's pretty simple and you can see the loop that is causing your problems: https://github.com/python/cpython/blob/3.2/Lib/socket.py#L408

Upvotes: 8

Related Questions