从zmq.error.ZMQError恢复:已在使用的地址

时间:2013-10-03 12:54:34

标签: python sockets unix zeromq amqp

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

那究竟谁在使用这个地址?

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

3 个答案:

答案 0 :(得分:19)

问题1:

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

问题2:

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

答案 1 :(得分:2)

有时,另一个使用zeromq的进程会保持端口正在使用,而netstat并不表示其他进程正在侦听(因此netstat -lntp无法显示该进程),而是显示端口上已建立的连接,两端具有相同的主机/端口。在杀死其他进程后,该端口现在可供使用。

原因#1:我发生了这种情况,因为我在短暂的端口(在Linux上,例如32768-61000)设置了zeromq监听端口,这些端口被用作传出连接的本地端,并且我的服务需要连接到同一个盒子上的其他服务。传出连接获得与框上的侦听端口相同的短暂端口的时间百分比,突然&#34;地址已在使用&#34;。我只是将所有侦听端口移出了短暂的端口范围,并且已经使用了所有的#34;地址&#34;问题消失了。

原因#2:推测:当我遇到与其他python网络库类似的问题时,先前使用子进程或类似方法从侦听进程启动了有问题的进程,并且套接字泄漏到了儿童过程;如果父进程退出而没有关闭套接字,则套接字将保持活动并由子进程拥有,即使子进程对套接字真的一无所知,它仍然会被阻塞,因此其他进程无法进行#39; t使用它。

如果这是问题,可以通过在子进程之前调整套接字的标志来修复它,例如, (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)

或许还有一种方法可以更好地关闭父进程中的套接字。

答案 2 :(得分:1)

此时此刻:

reboot

下一步:

开始使用try: / except: / finally:封装构造函数,这将帮助您从所有zmq分配授予gracefull退出,包括。所有套接字 -s'.close()上下文.Term()没有任何挂起的orphan(s)内存泄漏,即使以防万一任何紧急按钮或未处理的异常都会中断您的代码执行,同时丢失对您的stil挂起,网络硬件绑定,实例的引用。