ZeroMQ:重新绑定套接字时的地址使用错误

时间:2014-03-26 09:14:53

标签: c++ visual-studio-2008 zeromq

将ZeroMQ套接字绑定到端点并关闭套接字后,将另一个套接字绑定到同一端点需要多次尝试。之前调用zmq_bind直到成功调用失败,并显示错误“正在使用的地址”(EADDRINUSE)。

以下代码演示了此问题:

#include <cassert>
#include <iostream>

#include "zmq.h"

int main() {
    void *ctx = zmq_ctx_new();
    assert( ctx );
    void *skt;

    skt = zmq_socket( ctx, ZMQ_REP );
    assert( skt );
    assert( zmq_bind( skt, "tcp://*:5555" ) == 0 );
    assert( zmq_close( skt ) == 0 );

    skt = zmq_socket( ctx, ZMQ_REP );
    assert( skt );
    int fail = 0;
    while ( zmq_bind( skt, "tcp://*:5555" ) ) { ++fail; }
    std::cout << fail << std::endl;
}

我在Windows XP SP3上使用ZeroMQ 4.0.3,编译器是VS 2008. libzmq.dll是使用提供的Visual Studio解决方案构建的。

当执行“Debug”构建(上面的代码和libzmq.dll)和1使用“Release”构建时,这会打印0。很奇怪,当使用混合构建配置(使用Release lib调试)运行上面的代码时,fail计数最多为6。

2 个答案:

答案 0 :(得分:2)

Pieter Hintjens给了我提示on the mailing list

zmq_close的调用会启动套接字关闭。这是在一个特殊的收割机中完成的。 ZeroMQ启动的线程调用zmq_close异步和非阻塞。请参阅有关ZeroMQ架构的白皮书中的"The reaper thread"

上面的代码不会等待线程执行实际工作,因此端点不会立即可用。

答案 1 :(得分:1)

当TCP套接字关闭时,它进入名为TIME_WAIT的状态。这意味着当套接字处于该状态时,它并没有真正关闭,这反过来意味着套接字使用的地址在离开状态之前是不可用的。

因此,如果您连续两次运行程序,那么当您尝试第二次运行时,套接字将从第一次运行时处于此TIME_WAIT状态,并且您会收到类似的错误。

您可能需要read more about TCP,尤其是operation and states