C++ 使用0MQ通过TCP连接到第一个可用端口

C++ 使用0MQ通过TCP连接到第一个可用端口,c++,sockets,zeromq,C++,Sockets,Zeromq,我正在编写一个分布式搜索算法,在该算法中,代理需要在TCP套接字上侦听传入的连接。在某个时刻,代理应该绑定一个空闲的TCP端口。端口号不重要,但代理应将其侦听端口号发送给其他代理 我想这是正确的做法: socket.bind("tcp://*:0"); 套接字绑定成功,但如何获取套接字绑定到的端口号?我在zmq\u getsockopt手册页中看不到任何返回端口号的选项代码 使用Zeromq,您可以使用字符串绑定或连接。它从protecol开始,tcp://在您的情况下,这是正确的。然后您有一

我正在编写一个分布式搜索算法,在该算法中,代理需要在TCP套接字上侦听传入的连接。在某个时刻,代理应该绑定一个空闲的TCP端口。端口号不重要,但代理应将其侦听端口号发送给其他代理

我想这是正确的做法:

socket.bind("tcp://*:0");

套接字绑定成功,但如何获取套接字绑定到的端口号?我在
zmq\u getsockopt
手册页中看不到任何返回端口号的选项代码

使用Zeromq,您可以使用字符串绑定或连接。它从protecol开始,
tcp://
在您的情况下,这是正确的。然后您有一个代表所有可用设备的
'*'
。然后,在本例中,以端口号
:0
结束

socket.bind("tcp://*:2424)
将尝试在端口2424绑定。如果运行man zmq_tcp,他们建议端口号大于1024。基本上,您应该提前知道端口号,而不是在绑定之后。在较新版本3.2中,还可以指定端口:0或:*然后操作系统将决定端口的位置。这可以通过socket.getsockopt()检索,如下一个示例所示:

zmq::context_t context(1);
zmq::socket_t sock(context, ZMQ_REP);
char port[1024]; //make this sufficiently large. 
                 //otherwise an error will be thrown because of invalid argument. 
size_t size = sizeof(port);
try{
    sock.bind("tcp://*:*");
}
catch (zmq::error_t&e ){
    cerr << "couldn't bind to socket: " << e.what();
    return e.num();
}
sock.getsockopt( ZMQ_LAST_ENDPOINT, &port, &size );
cout << "socket is bound at port " << port << endl;
因此,您仍然需要从字符串中解析53269“tcp://0.0.0.0:53269"
希望这对你有所帮助

@soroush你最后的评论有一种奇怪的拼写错误。我想你打算写“端口号”。我不知道是否可以让操作系统来决定,但我看了看。哎呀!很抱歉;)它不再可编辑(有人杀了我),所以我删除了。这是可能的,并且已经是zmq中的一个可用功能。描述如何正确执行此操作。但它不是用C++工作的。我认为这是一个带有ZMQ C++端口的bug。我还没有用C测试过…@soroush你用的是3.2版吗?我使用了2版本X。但是根据C-API(版本3.2),如果你将它传递给Socket。GETySockopt(),你可以使用ZMQYLASTHYSTEPOTION,因为C++ API包含了C API。另外,字符串应该是tcp://*:*@soroush我已经更新了我的答案,以更好地满足您的条件。我不同意您关于应该提前知道端口号的说法。即使在绑定到某个端口之前检查该端口是否可用,在检查和绑定尝试之间该端口仍可能不可用。因此,我更喜欢使用
getsockopt
的示例。属性
socket.LAST_ENDPOINT
应该具有解析的绑定地址。使用这种方法也是一个好主意。
socket is bound at port tcp://0.0.0:53269