2014-03-26 91 views
2

將ZeroMQ套接字綁定到端點並關閉套接字後,將另一個套接字綁定到同一端點需要多次嘗試。先前調用zmq_bind,直到成功的一個失敗並出現錯誤「Address in use」(EADDRINUSE)。ZeroMQ:重新綁定套接字時使用的地址錯誤

下面的代碼演示了此問題:

#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; 
} 

我使用ZeroMQ 4.0.3在Windows XP SP3,編譯器是2008年VS libzmq.dll已建成所提供的Visual Studio解決方案。

這裏打印1當做一個「調試」版本(上面的代碼和libzmq.dll)和0使用「版本」版本。奇怪的是,使用混合構建配置(Debug with Release lib)運行上述代碼時,fail的計數最多爲6.

回答

1

彼得·欣喬斯給我的暗示on the mailing list

zmq_close調用啓動套接字關閉。這是在ZeroMQ啓動的一個特殊的「收割者」線程中完成的,以便撥打zmq_close的異步和非阻塞。請參閱"The reaper thread"關於ZeroMQ架構的白皮書。

上面的代碼不會等待線程做實際工作,使端點不會立即變得可用。

0

當TCP套接字關閉時,它將進入一個名爲TIME_WAIT的狀態。這意味着,雖然套接字處於該狀態,但它並未真正關閉,這意味着套接字使用的地址在離開狀態之前不可用。

所以如果你連續運行你的程序兩次,套接字將在第一次運行時處於TIME_WAIT狀態,當你嘗試第二次運行時,你會得到這樣的錯誤。

你可能想read more about TCP,特別是有關其operation and states

+0

查看提供的TCP狀態圖,可以在達到SYN_RCVD或ESTABLISHED後輸入'TIME_WAIT'。請注意,重新綁定在程序內工作(幾微秒後)。運行程序*緊密連貫*起作用。 – mkluwe

相關問題