有没有办法重新打开套接字?

dug*_*res 7 python sockets

我在一些代码中创建了许多"短期"套接字,如下所示:

nb=1000
for i in range(nb):
    sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sck.connect((adr, prt)
    sck.send('question %i'%i)
    sck.shutdown(SHUT_WR)
    answer=sck.recv(4096)
    print 'answer %i : %s' % (%i, answer)
    sck.close()
Run Code Online (Sandbox Code Playgroud)

这个工作正常,只要nb足够"小".

由于NB可能是相当大的,虽然,我想这样做

sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sck.connect((adr, prt)
for i in range(nb):
    reopen(sck) # ? ? ?
    sck.send('question %i'%i)
    sck.shutdown(SHUT_WR)
    answer=sck.recv(4096)
    print 'answer %i : %s' % (%i, answer)
sck.close()
Run Code Online (Sandbox Code Playgroud)

所以问题是:
有没有办法"重用"已经关闭的套接字?

pax*_*blo 17

不,这是底层C套接字(以及TCP/IP协议)的限制.我的问题是:当你可以构建应用程序来使用它们时,为什么要关闭它们?

许多短期套接字的问题在于关闭它们使它们处于一段时间不能使用的状态(基本上是数据包生命周期的两倍,以确保网络中的任何数据包到达并被丢弃,或被丢弃由网络本身).基本上会发生的事情是,在需要唯一的4元组(源IP,源端口,目标IP,目标端口)中,第一个和后两个往往总是相同的,所以当你用完源代码时港口,你被冲洗了.

我们已经在软件中解决了这个问题,之后只有当我们在更快的机器上运行时才变得明显(因为我们可以使用更多的会话).

为什么不打开插座并继续使用它?看起来您的协议是一个简单的请求/响应协议,应该可以轻松地使用该方法.

就像是:

sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sck.connect((adr, prt)
for i in range(nb):
    sck.send('question %i'%i)
    answer=sck.recv(4096)
    print 'answer %i : %s' % (%i, answer)
sck.close()
Run Code Online (Sandbox Code Playgroud)

更新:

如果由于持续打开/关闭而导致连接不足,那么一种可能性(之前我们已经完成此操作)就是检测问题并加以限制.考虑下面的代码(我添加的东西比Python更多的伪代码,因为我已经很长时间没有触及Python了):

for i in range(nb):
    sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sck.connect((adr, prt)

    while sck.error() == NO_SOCKETS_AVAIL:
        sleep 250 milliseconds
        sck.connect((adr, prt)

    sck.send('question %i'%i)
    sck.shutdown(SHUT_WR)
    answer=sck.recv(4096)
    print 'answer %i : %s' % (%i, answer)
    sck.close()
Run Code Online (Sandbox Code Playgroud)

基本上,它可让您在有足够资源的同时全速运行,但在遇到问题区域时速度会变慢.这实际上是我们对我们的产品所做的,以"解决"资源不足时失败的问题.我们会重新构建它,除了它是一个接近使用寿命的遗留产品,我们基本上处于固定最低成本模式的服务.