擅长:python、mysql、java
<p>有时,另一个使用zeromq的进程正在使用端口,而<code>netstat</code>并不表示其他进程正在侦听(因此<code>netstat -lntp</code>不会显示它),而是显示端口上已建立的连接,两端具有相同的主机/端口。在终止另一个进程之后,端口现在可以使用了。</p>
<p>原因#1:发生这种情况的原因是,我将zeromq侦听端口设置在临时端口范围内(在linux上,例如32768-61000),这些端口用作传出连接的本地端,而我的服务需要连接到同一个盒子上的其他服务。传出连接获取与盒上的侦听端口相同的临时端口并突然“地址已在使用”的时间百分比。我刚刚把所有监听端口移到临时端口范围之外,所有“地址已在使用”的问题都消失了。</p>
<p>原因#2:推测:当我遇到其他python网络库的类似问题时,违规进程先前是使用subprocess或类似程序从侦听进程启动的,并且套接字泄漏到子进程时出现问题;如果父进程退出而没有关闭套接字,则套接字将是让子进程保持活动状态并拥有它,即使子进程并不真正了解套接字,它仍然会被保留,因此其他进程无法使用它。</p>
<p>如果这是问题所在,则可以通过调整子进程之前的套接字标志来解决,例如(特定于unix):</p>
<pre><code>fd = sock.get(zmq.FD)
old_flags = fcntl.fcntl(fd, fcntl.F_GETFD)
fcntl.fcntl(fd, fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC)
</code></pre>
<p>或者可能有一种方法可以更正确地关闭父进程中的套接字。</p>