是否可以在 ZMQ_PAIR 套接字原型上使用 zmq::poll() ?
Is it possible to use a zmq::poll() on a ZMQ_PAIR socket archetype?
是否可以将 zmq::poll
与 ZMQ_PAIR
类型的套接字一起使用?我有以下代码:
zmq::context_t ctx;
// create an in-process publisher for testing purposes
zmq::socket_t pub( ctx, ZMQ_PAIR );
pub.connect( "inproc://SelectTest_oneMessage" );
SendString( pub, "test-message" );
// create an in-process subscriber for testing purposes
zmq::socket_t sub( ctx, ZMQ_PAIR );
sub.bind( "inproc://SelectTest_oneMessage" );
zmq::pollitem_t sel[1];
sel[0].socket = ⊂
sel[0].events = ZMQ_POLLIN;
int rc = zmq::poll( sel, 1, -1 );
ASSERT_TRUE( sel[0].revents & ZMQ_POLLIN );
zmq::message_t msg;
ASSERT_NE( sub.recv( &msg ), 0 );
ASSERT_NE( sub.recv( &msg ), 0 );
但调用 zmq::poll
失败并出现异常:
Socket operation on non-socket
我在这里做错了什么?或者这是 ZMQ_PAIR
套接字的预期行为?
不,不禁止 .poll()
在 ZMQ_PAIR
端点 ( sub
)
在 .bind()
之前 .connect()
似乎有问题
API 说这个 (强调):
When connecting a socket to a peer address using zmq_connect()
with the inproc
transport, the endpoint shall be interpreted as an arbitrary string identifying the name to connect to. Before version 4.0 he name must have been previously created by assigning it to at least one socket within the same ØMQ context as the socket being connected. Since version 4.0 the order of zmq_bind()
and zmq_connect()
does not matter just like for the tcp transport type.
找到狗被埋葬的确切位置:
// >>>
// Report 0MQ version
//
/* ----------------------------------------------------------------- */
int major, minor, patch;
zmq_version ( &major, &minor, &patch ); std::cout << "[INF] ZeroMQ USES 0MQ-API version" << major << "." << minor << "." << patch << std::endl;
/* ----------------------------------------------------------------- */
zmq::context_t pure_inproc_ctx( 0 ); std::cout << "[INF] ZeroMQ CREATED a Zero-IOthreads .Context()-instance for pure-inproc:// transport-classes operations" << std::endl;
zmq::socket_t pub( pure_inproc_ctx, ZMQ_PAIR ); std::cout << "[INF] ZeroMQ DONE [pub] socket instantiation" << std::endl;
zmq::socket_t sub( pure_inproc_ctx, ZMQ_PAIR ); std::cout << "[INF] ZeroMQ DONE [sub] socket instantiation" << std::endl;
sub.setsockopt( ZMQ_LINGER, 0, 1 ); /* .setsockopt() */ std::cout << "[INF] ZeroMQ DONE [sub].setsockopt()" << std::endl;
sub.bind( "inproc://SelectTest_oneMessage" ); /* .bind() */ std::cout << "[INF] ZeroMQ DONE [sub].bind()" << std::endl;
pub.setsockopt( ZMQ_LINGER, 0, 1 ); /* .setsockopt() */ std::cout << "[INF] ZeroMQ DONE [pub].setsockopt()" << std::endl;
pub.connect( "inproc://SelectTest_oneMessage" ); /* .connect() */ std::cout << "[INF] ZeroMQ DONE [pub].connect()" << std::endl;
zmq::message_t aMessageToSEND ( 5 );
memcpy ( aMessageToSEND.data (), "Hello", 5 ); std::cout << "[INF] ZeroMQ CREATED a [Hello] Message" << std::endl;
pub.send ( aMessageToSEND ); std::cout << "[INF] ZeroMQ SENT a Message via [pub].send()" << std::endl;
zmq::pollitem_t sel[1];
sel[0].socket = sub;
sel[0].events = ZMQ_POLLIN; std::cout << "[INF] ZeroMQ DONE a .Poller() setup" << std::endl;
std::cout << "[INF] ZeroMQ WILL wait HERE infinitely for a first .Poller.poll() for a [sub].POLLIN Event" << std::endl;
int rc = zmq::poll( &sel [0], 1, -1 ); std::cout << "[INF] ZeroMQ EXIT from wait-state on a first .Poller.poll() [sub].POLLIN Event" << std::endl;
ASSERT_TRUE( sel[0].revents & ZMQ_POLLIN ); std::cout << "[INF] ZeroMQ DONE test on a first .Poller.poll() [sub].POLLIN Event" << std::endl;
zmq::message_t aMessageToRECV; std::cout << "[INF] ZeroMQ CREATED a aMessageToRECV Message-container instance" << std::endl;
ASSERT_NE( sub.recv( &aMessageToRECV ), 0 ); std::cout << "[INF] ZeroMQ DONE 1st test on [sub].recv() to immediately load aMessageToRECV-container" << std::endl;
ASSERT_NE( sub.recv( &aMessageToRECV ), 0 ); std::cout << "[INF] ZeroMQ DONE 2nd test on [sub].recv() to immediately load an already loaded container" << std::endl;
问题出在这一行:
sel[0].socket = ⊂
&
不应该在那里。将此更改为后代码有效:
sel[0].socket = sub;
很难发现这个问题,因为该结构的 socket
字段是 void *
,这意味着类型检查器在任何情况下都不会报错。
是否可以将 zmq::poll
与 ZMQ_PAIR
类型的套接字一起使用?我有以下代码:
zmq::context_t ctx;
// create an in-process publisher for testing purposes
zmq::socket_t pub( ctx, ZMQ_PAIR );
pub.connect( "inproc://SelectTest_oneMessage" );
SendString( pub, "test-message" );
// create an in-process subscriber for testing purposes
zmq::socket_t sub( ctx, ZMQ_PAIR );
sub.bind( "inproc://SelectTest_oneMessage" );
zmq::pollitem_t sel[1];
sel[0].socket = ⊂
sel[0].events = ZMQ_POLLIN;
int rc = zmq::poll( sel, 1, -1 );
ASSERT_TRUE( sel[0].revents & ZMQ_POLLIN );
zmq::message_t msg;
ASSERT_NE( sub.recv( &msg ), 0 );
ASSERT_NE( sub.recv( &msg ), 0 );
但调用 zmq::poll
失败并出现异常:
Socket operation on non-socket
我在这里做错了什么?或者这是 ZMQ_PAIR
套接字的预期行为?
不,不禁止 .poll()
在 ZMQ_PAIR
端点 ( sub
)
在 .bind()
.connect()
似乎有问题
API 说这个 (强调):
When connecting a socket to a peer address using
zmq_connect()
with theinproc
transport, the endpoint shall be interpreted as an arbitrary string identifying the name to connect to. Before version 4.0 he name must have been previously created by assigning it to at least one socket within the same ØMQ context as the socket being connected. Since version 4.0 the order ofzmq_bind()
andzmq_connect()
does not matter just like for the tcp transport type.
找到狗被埋葬的确切位置:
// >>>
// Report 0MQ version
//
/* ----------------------------------------------------------------- */
int major, minor, patch;
zmq_version ( &major, &minor, &patch ); std::cout << "[INF] ZeroMQ USES 0MQ-API version" << major << "." << minor << "." << patch << std::endl;
/* ----------------------------------------------------------------- */
zmq::context_t pure_inproc_ctx( 0 ); std::cout << "[INF] ZeroMQ CREATED a Zero-IOthreads .Context()-instance for pure-inproc:// transport-classes operations" << std::endl;
zmq::socket_t pub( pure_inproc_ctx, ZMQ_PAIR ); std::cout << "[INF] ZeroMQ DONE [pub] socket instantiation" << std::endl;
zmq::socket_t sub( pure_inproc_ctx, ZMQ_PAIR ); std::cout << "[INF] ZeroMQ DONE [sub] socket instantiation" << std::endl;
sub.setsockopt( ZMQ_LINGER, 0, 1 ); /* .setsockopt() */ std::cout << "[INF] ZeroMQ DONE [sub].setsockopt()" << std::endl;
sub.bind( "inproc://SelectTest_oneMessage" ); /* .bind() */ std::cout << "[INF] ZeroMQ DONE [sub].bind()" << std::endl;
pub.setsockopt( ZMQ_LINGER, 0, 1 ); /* .setsockopt() */ std::cout << "[INF] ZeroMQ DONE [pub].setsockopt()" << std::endl;
pub.connect( "inproc://SelectTest_oneMessage" ); /* .connect() */ std::cout << "[INF] ZeroMQ DONE [pub].connect()" << std::endl;
zmq::message_t aMessageToSEND ( 5 );
memcpy ( aMessageToSEND.data (), "Hello", 5 ); std::cout << "[INF] ZeroMQ CREATED a [Hello] Message" << std::endl;
pub.send ( aMessageToSEND ); std::cout << "[INF] ZeroMQ SENT a Message via [pub].send()" << std::endl;
zmq::pollitem_t sel[1];
sel[0].socket = sub;
sel[0].events = ZMQ_POLLIN; std::cout << "[INF] ZeroMQ DONE a .Poller() setup" << std::endl;
std::cout << "[INF] ZeroMQ WILL wait HERE infinitely for a first .Poller.poll() for a [sub].POLLIN Event" << std::endl;
int rc = zmq::poll( &sel [0], 1, -1 ); std::cout << "[INF] ZeroMQ EXIT from wait-state on a first .Poller.poll() [sub].POLLIN Event" << std::endl;
ASSERT_TRUE( sel[0].revents & ZMQ_POLLIN ); std::cout << "[INF] ZeroMQ DONE test on a first .Poller.poll() [sub].POLLIN Event" << std::endl;
zmq::message_t aMessageToRECV; std::cout << "[INF] ZeroMQ CREATED a aMessageToRECV Message-container instance" << std::endl;
ASSERT_NE( sub.recv( &aMessageToRECV ), 0 ); std::cout << "[INF] ZeroMQ DONE 1st test on [sub].recv() to immediately load aMessageToRECV-container" << std::endl;
ASSERT_NE( sub.recv( &aMessageToRECV ), 0 ); std::cout << "[INF] ZeroMQ DONE 2nd test on [sub].recv() to immediately load an already loaded container" << std::endl;
问题出在这一行:
sel[0].socket = ⊂
&
不应该在那里。将此更改为后代码有效:
sel[0].socket = sub;
很难发现这个问题,因为该结构的 socket
字段是 void *
,这意味着类型检查器在任何情况下都不会报错。