Python 3.2.3:Socket超时的时间比它应该的时间长?

Python 3.2.3:Socket超时的时间比它应该的时间长?,python,windows,sockets,networking,Python,Windows,Sockets,Networking,我在Windows7上使用Python3.2.3,我有一段代码通过一个阻塞套接字连接到一个服务器,该套接字具有用户指定的超时值。代码很简单: testconn = socket.create_connection((host, port), timeout) 代码运行良好,除了一个奇怪的事实,超时似乎比无效请求的超时时间要长。我故意尝试连接到www.google.com:59855(随机端口意味着它应该尝试连接,直到达到超时),超时时间为5秒,但似乎至少需要15秒才能超时 是否有任何可能的原因

我在Windows7上使用Python3.2.3,我有一段代码通过一个阻塞套接字连接到一个服务器,该套接字具有用户指定的超时值。代码很简单:

testconn = socket.create_connection((host, port), timeout)
代码运行良好,除了一个奇怪的事实,超时似乎比无效请求的超时时间要长。我故意尝试连接到www.google.com:59855(随机端口意味着它应该尝试连接,直到达到超时),超时时间为5秒,但似乎至少需要15秒才能超时


是否有任何可能的原因,和/或任何修复?(如果不可修复,这不是一个大问题,但还是希望有一个解决方案。)提前感谢。

这不是Python 3或Windows特有的问题。请看一下create_connection()的文档:

重要的片段是:

如果主机是非数字主机名,它将尝试解析这两个主机名 AF_INET和AF_INET6,然后尝试连接到所有可能的 依次寻址,直到连接成功

它使用socket.getaddrinfo解析名称。如果你跑

socket.getaddrinfo('google.com', 59855, 0, socket.SOCK_STREAM)
您可能会返回一些结果。当您调用socket.create_connection时,它将迭代所有这些结果,每个结果都等待超时秒,直到失败。因为它为每个结果等待超时秒,所以总时间显然将大于超时

如果您使用IP地址而不是主机名调用create_connection,例如

testconn = socket.create_connection(('74.125.226.201', 59855), timeout=5)
你应该得到5秒的超时时间

如果你真的很好奇,看看create_connection的源代码。这非常简单,您可以看到导致问题的循环:

这不是Python 3或Windows特有的问题。请看一下create_connection()的文档:

重要的片段是:

如果主机是非数字主机名,它将尝试解析这两个主机名 AF_INET和AF_INET6,然后尝试连接到所有可能的 依次寻址,直到连接成功

它使用socket.getaddrinfo解析名称。如果你跑

socket.getaddrinfo('google.com', 59855, 0, socket.SOCK_STREAM)
您可能会返回一些结果。当您调用socket.create_connection时,它将迭代所有这些结果,每个结果都等待超时秒,直到失败。因为它为每个结果等待超时秒,所以总时间显然将大于超时

如果您使用IP地址而不是主机名调用create_connection,例如

testconn = socket.create_connection(('74.125.226.201', 59855), timeout=5)
你应该得到5秒的超时时间

如果你真的很好奇,看看create_connection的源代码。这非常简单,您可以看到导致问题的循环:

如果指定超时,则套接字不再处于阻塞模式。请参阅套接字模块文档。有一件事你搞错了。如果它得到一个“连接被拒绝”,它将立即失败而不重试。重试是针对没有收到回复的情况。@RolandSmith我在文档中看不到任何地方有这样的内容,而且也没有任何意义。非阻塞连接将立即返回,而不是超时。@EJP:A quote:“套接字对象可以处于三种模式之一:阻塞、非阻塞或超时。”来自@RolandSmith,这是一篇很差的文档。在后台,即在SocketsAPI和内核中,只有阻塞和非阻塞模式:超时只是阻塞模式中的另一个错误。引入第三种“模式”违反了Ockham的razor。如果指定超时,则套接字不再处于阻塞模式。请参阅套接字模块文档。有一件事你搞错了。如果它得到一个“连接被拒绝”,它将立即失败而不重试。重试是针对没有收到回复的情况。@RolandSmith我在文档中看不到任何地方有这样的内容,而且也没有任何意义。非阻塞连接将立即返回,而不是超时。@EJP:A quote:“套接字对象可以处于三种模式之一:阻塞、非阻塞或超时。”来自@RolandSmith,这是一篇很差的文档。在后台,即在SocketsAPI和内核中,只有阻塞和非阻塞模式:超时只是阻塞模式中的另一个错误。引入第三种“模式”违反了奥卡姆的剃须刀。