ZeroMQ: Address in use error when re-binding socket

匿名 (未验证) 提交于 2019-12-03 00:57:01

问题:

After binding a ZeroMQ socket to an endpoint and closing the socket, binding another socket to the same endpoint requires several attempts. The previous calls to zmq_bind up until the successful one fail with the error "Address in use" (EADDRINUSE).

The following code demonstrates the problem:

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

I'm using ZeroMQ 4.0.3 on Windows XP SP3, compiler is VS 2008. libzmq.dll has been built with the provided Visual Studio solution.

This prints 1 here when doing a "Debug" build (both of the code above and of libzmq.dll) and 0 using a "Release" build. Strange enough, when running the code above with mixed build configuration (Debug with Release lib), fail counts up to 6.

回答1:

Pieter Hintjens gave me the hint on the mailing list:

The call to zmq_close initiates the socket shutdown. This is done in a special "reaper" thread started by ZeroMQ to make the call to zmq_close asynchronous and non-blocking. See "The reaper thread" in a whitepaper about ZeroMQ's architecture.

The code above does not wait for the thread doing the actual work, so the endpoint will not become available immediately.



回答2:

When a TCP socket is closed, it enters a state called TIME_WAIT. This means that while the socket is in that state, it's not really closed, and that in turn means that the address used by the socket is not available until it leave the state.

So if you run your program two times in close succession the socket will be in this TIME_WAIT state from the first run when you try the second run, and you get an error like this.

You might want to read more about TCP, and especially about its operation and states.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!