我在运行PAIR
与 ZMQ 的模式(非阻塞客户端服务器)连接时按了 Ctrl-C。后来当我尝试运行REQ-REP
(阻塞客户端单服务器连接)模式时,我不断收到Address already in use
错误消息。我试过运行 netstat ,netstat -ltnp | grep :<my port>
但没有列出任何进程。
那么究竟是谁在使用这个地址呢?
另外,如何优雅地关闭这样的套接字连接?
问题一:
如果您这样做sudo netstat -ltnp
,在 Linux 类型的操作系统上,您很可能会看到拥有该端口的进程。用 杀死它kill -9 <pid>
。
问题2:
当您退出程序时,关闭您的套接字,然后调用 zmq_ctx_destroy()。这破坏了上下文。有关更多信息,请参阅http://zguide.zeromq.org/page:all#toc17。
reboot
开始使用try:
//封装构造函数except:
,finally:
这将帮助您从所有 zmq 分配中优雅退出,包括。所有Socket -s'和.close()
Context没有.term()
任何挂起的孤儿和内存泄漏,即使任何紧急按钮或未处理的异常都会完全中断您的代码执行并丢失对您仍然挂起的网络硬件绑定的引用, 实例。
有时另一个使用 zeromq 的进程正在使用该端口,并且netstat
并不表示其他进程正在侦听(因此netstat -lntp
不会显示它),而是显示端口上已建立连接,两端具有相同的主机/端口。杀死其他进程后,该端口现在可以使用了。
原因 #1:我发生这种情况是因为我在临时端口范围内设置了 zeromq 侦听端口(在 linux 上,例如 32768-61000),这些端口用作传出连接的本地端,并且我的服务需要连接到同一个盒子上的其他服务。传出连接获得与盒子上的侦听端口相同的临时端口的时间百分比,突然“地址已在使用中”。我只是将所有监听端口移到临时端口范围之外,所有“地址已在使用”问题都消失了。
原因2:推测:当我遇到其他python网络库的类似问题时,有问题的进程之前是从使用子进程或类似的监听进程启动的,并且套接字泄漏到子进程存在问题;如果父进程在没有关闭套接字的情况下退出,则套接字将保持活动状态并由子进程拥有,即使子进程对套接字一无所知,它仍然会被阻止,因此其他进程无法用它。
如果这是问题所在,则可以通过在子进程之前调整套接字的标志来修复它,例如(特定于 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)
或者也许有一种方法可以更正确地关闭父进程中的套接字。