Python WSAECONN的快速检测或模拟

Python WSAECONN的快速检测或模拟,python,windows,sockets,winsock,Python,Windows,Sockets,Winsock,Windows套接字在WSAECONNREFUSED方面有一些奇怪的行为(这意味着积压已满或端口不可用,请参阅)。如果Windows检测到其中一种情况,它将以0.5s的间隔重试(最多)两次。这意味着在套接字连接尝试()上检测WSAECONNreference至少需要1秒 有没有办法在不影响注册表值的情况下加快检测速度?我需要在单元测试中模拟拒绝套接字连接。类似于用原始套接字模拟拒绝连接的解决方案也是可以接受的 下面是一个简单的Python脚本,演示了该问题: import errno impor

Windows套接字在WSAECONNREFUSED方面有一些奇怪的行为(这意味着积压已满或端口不可用,请参阅)。如果Windows检测到其中一种情况,它将以0.5s的间隔重试(最多)两次。这意味着在套接字连接尝试()上检测WSAECONNreference至少需要1秒

有没有办法在不影响注册表值的情况下加快检测速度?我需要在单元测试中模拟拒绝套接字连接。类似于用原始套接字模拟拒绝连接的解决方案也是可以接受的

下面是一个简单的Python脚本,演示了该问题:

import errno
import socket
import time

PORT = 50123


def main():
    s = socket.socket()
    s.bind(('127.0.0.1', PORT))
    s.listen(0)
    client = socket.socket()
    client.connect(('127.0.0.1', PORT))

    client2 = socket.socket()
    start = time.time()

    try:
        client2.connect(('127.0.0.1', PORT))
    except socket.error as e:
        assert e.errno == errno.WSAECONNREFUSED
        print 'connection attempt took', time.time() - start
    finally:
        client2.close()
        client.close()
        s.close()


if __name__ == '__main__':
    main()

这和你问的不完全一样。但是,如果您仅在单元测试中需要它,则库将非常有用

import errno
import socket
import time
import mock

PORT = 50123


def connect_mock(*agrs):
    raise socket.error(errno.WSAECONNREFUSED, "Testing")


def main():
    s = socket.socket()
    s.bind(('127.0.0.1', PORT))
    s.listen(0)
    client = socket.socket()
    client.connect(('127.0.0.1', PORT))

    client2 = socket.socket()
    start = time.time()

    with mock.patch('socket.socket.connect', connect_mock):
        try:
            client2.connect(('127.0.0.1', PORT))
            print "done"
        except socket.error as e:
            assert e.errno == errno.WSAECONNREFUSED
            print 'connection attempt took', time.time() - start
        finally:
            client2.close()
            client.close()
            s.close()


if __name__ == '__main__':
    main()

以下是我基于dmitry vakhrushev的解决方案,该解决方案使连接方法更加智能:

if sys.platform == 'win32':
    n_calls = [0]
    org_connect = socket.socket.connect

    def refusing_connect(*args):
        if n_calls[0] < 2:
            n_calls[0] += 1
            raise socket.error(errno.WSAECONNREFUSED, "Testing")
        return org_connect(*args)

    # patch socket.connect to speed up WSAECONNREFUSED detection
    patcher = mock.patch('socket.socket.connect', refusing_connect)
    patcher.start()
    self.addCleanup(patcher.stop)
如果sys.platform==“win32”:
n_调用=[0]
org_connect=socket.socket.connect
def\U连接(*参数):
如果n_调用[0]<2:
n_调用[0]+=1
升起插座。错误(errno.WSAECONNREFUSED,“测试”)
返回组织连接(*args)
#patch socket.connect可加速WSAECONN融合检测
patcher=mock.patch('socket.socket.connect',拒绝连接)
patcher.start()
self.addCleanup(patcher.stop)

实际上,我正在测试一个重新连接例程,因此第二次连接调用必须成功(因为我在注意到第一次连接尝试失败后启动了服务器)。但这应该可以通过更智能的
connect\u mock
实现。我将对此进行测试并报告我的进度。到目前为止,谢谢你的灵感。啊,这在我的情况下非常有效:)你肯定赢得了赏金,但我会再开放几天,因为可能会有一个更普遍的解决方案。