【问题标题】:Socket OSError [WinError 10022] when making connect() attempts too quickly进行 connect() 尝试过快时出现 Socket OSError [WinError 10022]
【发布时间】:2014-07-16 17:23:59
【问题描述】:

我有一个客户端需要反复轮询以查看预期的服务器是否在那里,并优雅​​地处理它可能长时间不存在的事实。

看下面的测试脚本:

import socket, time

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(0.1)

delay = 2
connected = False

while not connected:
    try:
        s.connect(("localhost", 50000))    # I'm running my test server locally
        connected = True

    except socket.timeout:
        print("Timed out. Waiting " + str(round(delay, 1)) + "s before next attempt.")
        time.sleep(delay)
        delay -= 0.1

结果:

Timed out. Waiting 2s before next attempt.
Timed out. Waiting 1.9s before next attempt.
Timed out. Waiting 1.8s before next attempt.
Timed out. Waiting 1.7s before next attempt.
Timed out. Waiting 1.6s before next attempt.
Timed out. Waiting 1.5s before next attempt.
Timed out. Waiting 1.4s before next attempt.
Timed out. Waiting 1.3s before next attempt.
Timed out. Waiting 1.2s before next attempt.
Timed out. Waiting 1.1s before next attempt.
Timed out. Waiting 1.0s before next attempt.
Timed out. Waiting 0.9s before next attempt.
Traceback (most recent call last):
  File "C:/Users/Lewis/Desktop/sockettest.py", line 11, in <module>
    s.connect(("localhost", 50000))
OSError: [WinError 10022] An invalid argument was supplied

看来,如果我在 connect() 尝试之间没有延迟大约 0.9 秒,我就会得到这个异常。

发生了什么事?

【问题讨论】:

  • 我想我见过这样的事情。它实际上是 MS Windows 中的一个设置,可以防止在短时间内建立许多连接。我不记得基本原理,但它与保护他人免受您计算机上行为不端的软件的侵害有关。不过,您可以通过注册表进行配置。
  • 有趣,有道理。我不打算用我的程序来接触这个注册表设置,我只需设置一个延迟就可以了。但是,我想看看我是否可以找到一些关于延迟可能是什么的文档,以及任何其他注意事项。我不喜欢盲目地设置延迟并希望它有效:)

标签: python windows sockets exception networking


【解决方案1】:

您为每个连接“尝试”使用一个套接字。一个套接字只能用于一个连接。您实际上只在此处进行了一次连接尝试。当它最终超时时,套接字会进入不允许您再调用connect 的状态。

为您要尝试的每个新连接尝试创建一个新套接字。

【讨论】:

  • 太好了,如果我每次都创建一个新套接字,我确实可以快速启动 connect() 尝试。虽然我的代码实际上只进行一次连接尝试,但我不明白如果我每次都使用同一个套接字,为什么需要这种看似任意的延迟。
  • 第二次在套接字上调用connect 不会尝试第二次连接。这就是 TCP 套接字的工作原理。
  • 我修改了我的客户端,使其尝试连接一次,然后等待 10 秒,然后再次尝试连接,两者都在同一个套接字上。在 10 秒的等待期间,我启动了主机。客户端第二次连接成功。我仍然不明白它是如何不尝试第二次连接的。看起来确实如此。
  • 第一次连接尝试仍在进行中。第二次调用connect 只是向系统询问连接尝试状态的一种方式。它将“工作”(成功或超时),直到连接尝试成功(连接被接受)或失败(连接被拒绝或达到内部 TCP 超时)。然后它就变成了一个错误。
  • 啊,明白了。所以连接尝试只有在我关闭套接字时才会真正被终止,即使它已经超时,对吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
  • 2017-09-05
  • 2020-12-30
  • 2016-02-05
  • 1970-01-01
  • 2015-02-06
  • 2015-04-15
相关资源
最近更新 更多