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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19159771/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 13:01:32  来源:igfitidea点击:

Recovering from zmq.error.ZMQError: Address already in use

pythonsocketsunixzeromqamqp

提问by Pratik Mandrekar

I hit Ctrl-C while running a PAIRpattern (non-blocking client servers) connection with ZMQ. Later when I tried running the REQ-REP(blocking client single server connection) pattern, I keep getting the Address already in useerror. I have tried running netstat with netstat -ltnp | grep :<my port>but that does not list any process.

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

So who exactly is using this address?

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

Also how does one gracefully shutdown socket connections like these?

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

回答by jorgen

Question 1:

问题 1:

If you do sudo netstat -ltnp, on a Linux type operating system, you will most probably see the process owning the port. Kill it with kill -9 <pid>.

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

Question 2:

问题2:

When you exit the program, close your sockets and then call zmq_ctx_destroy(). This destroys the context. See http://zguide.zeromq.org/page:all#toc17for more info.

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

回答by user3666197

At this very moment:

在这个非常时刻:

reboot

Next:

下一个:

start using try:/ except:/ finally:encapsulation constructors, that will help you to grant a graceful exitfrom all zmq allocations, incl. all Socket-s' .close()and Context's .term()without any hanging orphan(s) an memory leak(s), even in case any panic button or unhandled exception interrupts your code-execution altogether with losing references to your still hanging, network-hardware bound, instances.

开始使用try:/ except:/finally:封装构造,这将有助于您授予体面退出所有ZMQ分配,含。所有的Socket-s'.close()上下文.term(),没有任何悬挂孤儿(S)的内存泄漏(S),即使在任何情况下紧急按钮或者未处理的异常与失去引用约束你还挂着,网络硬件完全中断您的代码执行,实例。

回答by rakslice

Sometimes another zeromq-using process is keeping the port in use, and netstatdoesn't indicate that other process listening (so netstat -lntpwon't show it), but rather shows an established connection on the port with the same host/port on both ends. After killing that other process, the port is now available for use.

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

Reason #1: I've had this happen because I had the zeromq listening ports set up in the range of ephemeral ports (on linux e.g. 32768-61000) that get used as the local side of outgoing connections, and my services need to connect to other services on the same box. A percentage of the time an outgoing connection gets an ephemeral port that is the same as a listening port on the box, and suddenly "address already in use". I just moved all the listening ports down out of the way of the ephemeral port range and all of the "address already in use" issues went away.

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

Reason #2: Speculation: When I've run into similar problems with other python network libraries, the offending process was previously launched from the listening process using subprocess or similar, and there was a problem with the socket leaking to the child process; if the parent process exited without closing the socket, the socket would be left alive and owned by the child process, and even though the child process didn't really know anything about the socket it would still be held up so other processes couldn't use it.

原因#2:推测:当我遇到其他python网络库的类似问题时,之前使用subprocess或类似方法从侦听进程启动了违规进程,并且存在socket泄漏到子进程的问题;如果父进程在没有关闭套接字的情况下退出,则套接字将保持活动状态并由子进程拥有,即使子进程对套接字一无所知,它仍然会被阻止,因此其他进程不能用它。

If that's the issue, it might be fixable by tweaking the flags of the socket before the subprocess, e.g. (unix-specific):

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

Or maybe there's a way to more properly close the socket in the parent process.

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