从zmq.error.ZMQError恢复:地址已在美国

2024-04-19 18:43:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我在使用ZMQ运行PAIR模式(非阻塞客户端服务器)连接时按了Ctrl-C。稍后,当我尝试运行REQ-REP(阻塞客户机-单服务器连接)模式时,我一直得到Address already in use错误。我试过用netstat -ltnp | grep :<my port>运行netstat,但是没有列出任何进程。

那么到底是谁在用这个地址?

另外,如何优雅地关闭这样的套接字连接?


Tags: in服务器客户端客户机useaddress错误模式
3条回答

问题1:

如果在Linux类型的操作系统上执行sudo netstat -ltnp,您很可能会看到拥有端口的进程。用kill -9 <pid>杀死它。

问题2:

退出程序时,请关闭套接字,然后调用zmq_ctx_destroy()。这会破坏上下文。有关详细信息,请参见http://zguide.zeromq.org/page:all#toc17

有时,另一个使用zeromq的进程正在使用端口,而netstat并不表示其他进程正在侦听(因此netstat -lntp不会显示它),而是显示端口上已建立的连接,两端具有相同的主机/端口。在终止另一个进程之后,端口现在可以使用了。

原因#1:发生这种情况的原因是,我将zeromq侦听端口设置在临时端口范围内(在linux上,例如32768-61000),这些端口用作传出连接的本地端,而我的服务需要连接到同一个盒子上的其他服务。传出连接获取与盒上的侦听端口相同的临时端口并突然“地址已在使用”的时间百分比。我刚刚把所有监听端口移到临时端口范围之外,所有“地址已在使用”的问题都消失了。

原因#2:推测:当我遇到其他python网络库的类似问题时,违规进程先前是使用subprocess或类似程序从侦听进程启动的,并且套接字泄漏到子进程时出现问题;如果父进程退出而没有关闭套接字,则套接字将是让子进程保持活动状态并拥有它,即使子进程并不真正了解套接字,它仍然会被保留,因此其他进程无法使用它。

如果这是问题所在,则可以通过调整子进程之前的套接字标志来解决,例如(特定于unix):

fd = sock.get(zmq.FD)
old_flags = fcntl.fcntl(fd, fcntl.F_GETFD)
fcntl.fcntl(fd, fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC)

或者可能有一种方法可以更正确地关闭父进程中的套接字。

此时此刻:

reboot

下一步:

开始使用try:/except:/finally:封装构造函数,这将帮助您从所有zmq分配(包括allSocket-s'.close()Context's.term())中获得优雅的退出,而不存在任何挂起的孤立内存泄漏,即使在任何死机按钮或未处理的异常中断代码执行的情况下,也会丢失对仍然挂起的、网络硬件绑定的实例的引用。

相关问题 更多 >