是否可以在 ZMQ_PAIR 套接字原型上使用 zmq::poll() ?

Is it possible to use a zmq::poll() on a ZMQ_PAIR socket archetype?

是否可以将 zmq::pollZMQ_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 = &sub;

& 不应该在那里。将此更改为后代码有效:

sel[0].socket = sub;

很难发现这个问题,因为该结构的 socket 字段是 void *,这意味着类型检查器在任何情况下都不会报错。