Можно ли использовать zmq::poll() для архетипа сокета ZMQ_PAIR?

Можно ли использовать 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 Розетки?

2 ответа

Решение

Проблема была в этой строке:

sel[0].socket = ⊂

& не должен был быть там. Код работает после изменения этого на:

sel[0].socket = sub;

Было трудно уловить эту проблему, потому что socket поле этой структуры является void *, что означает, что проверка типов не жалуется в любом случае.

Нет, это не запрещено .poll() на ZMQ_PAIR конечная точка (sub)

Беда кажется с .connect() до .bind()

API говорит это (выделение добавлено):

При подключении сокета к одноранговому адресу с помощью zmq_connect() с inproc транспорта, конечная точка должна интерпретироваться как произвольная строка, идентифицирующая имя для подключения. До версии 4.0 его имя должно было быть предварительно создано путем назначения его как минимум одному сокету в том же контексте ØMQ, что и подключаемый сокет. Начиная с версии 4.0, порядок zmq_bind() а также zmq_connect() не имеет значения, как для типа транспорта TCP.


Поймайте точную точку, где собака похоронена:

//                                                                      >>> https://stackru.com/a/44510552
//  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;
Другие вопросы по тегам