int test_basic() { void *ctx = zmq_ctx_new (); assert (ctx); // Create a publisher void *pub = zmq_socket (ctx, ZMQ_XPUB); assert (pub); int rc = zmq_bind (pub, "inproc://soname"); assert (rc == 0); // set pub socket options int manual = 1; rc = zmq_setsockopt(pub, ZMQ_XPUB_MANUAL, &manual, 4); assert (rc == 0); // Create a subscriber void *sub = zmq_socket (ctx, ZMQ_XSUB); assert (sub); rc = zmq_connect (sub, "inproc://soname"); assert (rc == 0); // Subscribe for A char subscription[2] = { 1, 'A'}; rc = zmq_send_const(sub, subscription, 2, 0); assert (rc == 2); char buffer[2]; // Receive subscriptions from subscriber rc = zmq_recv(pub, buffer, 2, 0); assert(rc == 2); assert(buffer[0] == 1); assert(buffer[1] == 'A'); // Subscribe socket for B instead rc = zmq_setsockopt(pub, ZMQ_SUBSCRIBE, "B", 1); assert(rc == 0); // Sending A message and B Message rc = zmq_send_const(pub, "A", 1, 0); assert(rc == 1); rc = zmq_send_const(pub, "B", 1, 0); assert(rc == 1); rc = zmq_recv(sub, buffer, 1, ZMQ_DONTWAIT); assert(rc == 1); assert(buffer[0] == 'B'); // Clean up. rc = zmq_close (pub); assert (rc == 0); rc = zmq_close (sub); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); return 0 ; }
int main (void) { setup_test_environment(); void *ctx = zmq_ctx_new (); assert (ctx); void *sb = zmq_socket (ctx, ZMQ_PAIR); assert (sb); int rc = zmq_bind (sb, "inproc://a"); assert (rc == 0); void *sc = zmq_socket (ctx, ZMQ_PAIR); assert (sc); rc = zmq_connect (sc, "inproc://a"); assert (rc == 0); bounce (sb, sc); // Test zmq_send_const rc = zmq_send_const (sb, "foo", 3, ZMQ_SNDMORE); assert (rc == 3); rc = zmq_send_const (sb, "foobar", 6, 0); assert (rc == 6); zmq_msg_t msg; rc = zmq_msg_init (&msg); assert (rc == 0); rc = zmq_msg_recv (&msg, sc, 0); assert (rc == 3); assert (zmq_msg_size (&msg) == 3); void* data = zmq_msg_data (&msg); assert (memcmp ("foo", data, 3) == 0); rc = zmq_msg_recv (&msg, sc, 0); assert (rc == 6); data = zmq_msg_data (&msg); assert (memcmp ("foobar", data, 6) == 0); // Cleanup rc = zmq_close (sc); assert (rc == 0); rc = zmq_close (sb); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); return 0 ; }
void test_connect_before_bind_pub_sub () { void *ctx = zmq_ctx_new (); assert (ctx); // Connect first void *connectSocket = zmq_socket (ctx, ZMQ_PUB); assert (connectSocket); int rc = zmq_connect (connectSocket, "inproc://cbbps"); assert (rc == 0); // Queue up some data, this will be dropped rc = zmq_send_const (connectSocket, "before", 6, 0); assert (rc == 6); // Now bind void *bindSocket = zmq_socket (ctx, ZMQ_SUB); assert (bindSocket); rc = zmq_setsockopt (bindSocket, ZMQ_SUBSCRIBE, "", 0); assert (rc == 0); rc = zmq_bind (bindSocket, "inproc://cbbps"); assert (rc == 0); // Wait for pub-sub connection to happen msleep (SETTLE_TIME); // Queue up some data, this not will be dropped rc = zmq_send_const (connectSocket, "after", 6, 0); assert (rc == 6); // Read pending message zmq_msg_t msg; rc = zmq_msg_init (&msg); assert (rc == 0); rc = zmq_msg_recv (&msg, bindSocket, 0); assert (rc == 6); void *data = zmq_msg_data (&msg); assert (memcmp ("after", data, 5) == 0); // Cleanup rc = zmq_close (connectSocket); assert (rc == 0); rc = zmq_close (bindSocket); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); }
void worker2(void* s) { const char worker_id = 2; char c; while (true) { int rc = zmq_recv(s, &c,1, 0); assert(rc == 1); assert(c == 1 || c == 0); if (c == 0) { msleep(10); rc = zmq_send_const(s,&worker_id, 1, 0); assert(rc == 1); } else { // we got exit request break; } } }
void test_multiple_connects () { const unsigned int no_of_connects = 10; void *ctx = zmq_ctx_new (); assert (ctx); int rc; void *connectSocket [no_of_connects]; // Connect first for (unsigned int i = 0; i < no_of_connects; ++i) { connectSocket [i] = zmq_socket (ctx, ZMQ_PUSH); assert (connectSocket [i]); rc = zmq_connect (connectSocket [i], "inproc://multiple"); assert (rc == 0); // Queue up some data rc = zmq_send_const (connectSocket [i], "foobar", 6, 0); assert (rc == 6); } // Now bind void *bindSocket = zmq_socket (ctx, ZMQ_PULL); assert (bindSocket); rc = zmq_bind (bindSocket, "inproc://multiple"); assert (rc == 0); for (unsigned int i = 0; i < no_of_connects; ++i) { // Read pending message zmq_msg_t msg; rc = zmq_msg_init (&msg); assert (rc == 0); rc = zmq_msg_recv (&msg, bindSocket, 0); assert (rc == 6); void *data = zmq_msg_data (&msg); assert (memcmp ("foobar", data, 6) == 0); } // Cleanup for (unsigned int i = 0; i < no_of_connects; ++i) { rc = zmq_close (connectSocket [i]); assert (rc == 0); } rc = zmq_close (bindSocket); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); }
void test_unbind () { void *ctx = zmq_ctx_new (); assert (ctx); // Bind and unbind socket 1 void *bindSocket1 = zmq_socket (ctx, ZMQ_PAIR); assert (bindSocket1); int rc = zmq_bind (bindSocket1, "inproc://unbind"); assert (rc == 0); zmq_unbind (bindSocket1, "inproc://unbind"); assert (rc == 0); // Bind socket 2 void *bindSocket2 = zmq_socket (ctx, ZMQ_PAIR); assert (bindSocket2); rc = zmq_bind (bindSocket2, "inproc://unbind"); assert (rc == 0); // Now connect void *connectSocket = zmq_socket (ctx, ZMQ_PAIR); assert (connectSocket); rc = zmq_connect (connectSocket, "inproc://unbind"); assert (rc == 0); // Queue up some data rc = zmq_send_const (connectSocket, "foobar", 6, 0); assert (rc == 6); // Read pending message zmq_msg_t msg; rc = zmq_msg_init (&msg); assert (rc == 0); rc = zmq_msg_recv (&msg, bindSocket2, 0); assert (rc == 6); void *data = zmq_msg_data (&msg); assert (memcmp ("foobar", data, 6) == 0); // Cleanup rc = zmq_close (connectSocket); assert (rc == 0); rc = zmq_close (bindSocket1); assert (rc == 0); rc = zmq_close (bindSocket2); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); }
static void pusher (void *ctx) { // Connect first void *connectSocket = zmq_socket (ctx, ZMQ_PAIR); assert (connectSocket); int rc = zmq_connect (connectSocket, "inproc://sink"); assert (rc == 0); // Queue up some data rc = zmq_send_const (connectSocket, "foobar", 6, 0); assert (rc == 6); // Cleanup rc = zmq_close (connectSocket); assert (rc == 0); }
void test_connect_before_bind () { void *ctx = zmq_ctx_new (); assert (ctx); // Connect first void *connectSocket = zmq_socket (ctx, ZMQ_PAIR); assert (connectSocket); int rc = zmq_connect (connectSocket, "inproc://cbb"); assert (rc == 0); // Queue up some data rc = zmq_send_const (connectSocket, "foobar", 6, 0); assert (rc == 6); // Now bind void *bindSocket = zmq_socket (ctx, ZMQ_PAIR); assert (bindSocket); rc = zmq_bind (bindSocket, "inproc://cbb"); assert (rc == 0); // Read pending message zmq_msg_t msg; rc = zmq_msg_init (&msg); assert (rc == 0); rc = zmq_msg_recv (&msg, bindSocket, 0); assert (rc == 6); void *data = zmq_msg_data (&msg); assert (memcmp ("foobar", data, 6) == 0); // Cleanup rc = zmq_close (connectSocket); assert (rc == 0); rc = zmq_close (bindSocket); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); }
int main (void) { setup_test_environment(); void *ctx = zmq_ctx_new (); assert (ctx); // Create a publisher void *pub = zmq_socket (ctx, ZMQ_PUB); assert (pub); int rc = zmq_bind (pub, "inproc://soname"); assert (rc == 0); // Create two subscribers void *sub1 = zmq_socket (ctx, ZMQ_SUB); assert (sub1); rc = zmq_connect (sub1, "inproc://soname"); assert (rc == 0); void *sub2 = zmq_socket (ctx, ZMQ_SUB); assert (sub2); rc = zmq_connect (sub2, "inproc://soname"); assert (rc == 0); // Subscribe pub1 to one prefix // and pub2 to another prefix. const char PREFIX1[] = "prefix1"; const char PREFIX2[] = "p2"; rc = zmq_setsockopt (sub1, ZMQ_SUBSCRIBE, PREFIX1, sizeof(PREFIX1)); assert (rc == 0); rc = zmq_setsockopt (sub2, ZMQ_SUBSCRIBE, PREFIX2, sizeof(PREFIX2)); assert (rc == 0); // Send a message with the first prefix rc = zmq_send_const(pub, PREFIX1, sizeof(PREFIX1), 0); assert (rc == sizeof(PREFIX1)); // sub1 should receive it, but not sub2 rc = zmq_recv (sub1, NULL, 0, ZMQ_DONTWAIT); assert (rc == sizeof(PREFIX1)); rc = zmq_recv (sub2, NULL, 0, ZMQ_DONTWAIT); assert (rc == -1); assert (errno == EAGAIN); // Send a message with the second prefix rc = zmq_send_const(pub, PREFIX2, sizeof(PREFIX2), 0); assert (rc == sizeof(PREFIX2)); // sub2 should receive it, but not sub1 rc = zmq_recv (sub2, NULL, 0, ZMQ_DONTWAIT); assert (rc == sizeof(PREFIX2)); rc = zmq_recv (sub1, NULL, 0, ZMQ_DONTWAIT); assert (rc == -1); assert (errno == EAGAIN); // Now invert the matching int invert = 1; rc = zmq_setsockopt (pub, ZMQ_INVERT_MATCHING, &invert, sizeof(invert)); assert (rc == 0); // ... on both sides, otherwise the SUB socket will filter the messages out rc = zmq_setsockopt (sub1, ZMQ_INVERT_MATCHING, &invert, sizeof(invert)); rc = zmq_setsockopt (sub2, ZMQ_INVERT_MATCHING, &invert, sizeof(invert)); assert (rc == 0); // Send a message with the first prefix rc = zmq_send_const(pub, PREFIX1, sizeof(PREFIX1), 0); assert (rc == sizeof(PREFIX1)); // sub2 should receive it, but not sub1 rc = zmq_recv (sub2, NULL, 0, ZMQ_DONTWAIT); assert (rc == sizeof(PREFIX1)); rc = zmq_recv (sub1, NULL, 0, ZMQ_DONTWAIT); assert (rc == -1); assert (errno == EAGAIN); // Send a message with the second prefix rc = zmq_send_const(pub, PREFIX2, sizeof(PREFIX2), 0); assert (rc == sizeof(PREFIX2)); // sub1 should receive it, but not sub2 rc = zmq_recv (sub1, NULL, 0, ZMQ_DONTWAIT); assert (rc == sizeof(PREFIX2)); rc = zmq_recv (sub2, NULL, 0, ZMQ_DONTWAIT); assert (rc == -1); assert (errno == EAGAIN); // Clean up. rc = zmq_close (pub); assert (rc == 0); rc = zmq_close (sub1); assert (rc == 0); rc = zmq_close (sub2); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); return 0 ; }
int main (void) { setup_test_environment (); void *ctx = zmq_ctx_new (); assert (ctx); // Create few sockets void *vent = zmq_socket (ctx, ZMQ_PUSH); assert (vent); int rc = zmq_bind (vent, "tcp://127.0.0.1:55556"); assert (rc == 0); void *sink = zmq_socket (ctx, ZMQ_PULL); assert (sink); rc = zmq_connect (sink, "tcp://127.0.0.1:55556"); assert (rc == 0); void *bowl = zmq_socket (ctx, ZMQ_PULL); assert (bowl); void *server = zmq_socket (ctx, ZMQ_SERVER); assert (server); rc = zmq_bind (server, "tcp://127.0.0.1:55557"); assert (rc == 0); void *client = zmq_socket (ctx, ZMQ_CLIENT); assert (client); // Set up poller void* poller = zmq_poller_new (); rc = zmq_poller_add_socket (poller, sink, sink); assert (rc == 0); // Send a message char data[1] = {'H'}; rc = zmq_send_const (vent, data, 1, 0); assert (rc == 1); // We expect a message only on the sink zmq_poller_event_t event; rc = zmq_poller_wait (poller, &event, -1); assert (rc == 0); assert (event.socket == sink); assert (event.user_data == sink); rc = zmq_recv (sink, data, 1, 0); assert (rc == 1); // Stop polling sink rc = zmq_poller_remove_socket (poller, sink); assert (rc == 0); // Check we can poll an FD rc = zmq_connect (bowl, "tcp://127.0.0.1:55556"); assert (rc == 0); #if defined _WIN32 SOCKET fd; size_t fd_size = sizeof (SOCKET); #else int fd; size_t fd_size = sizeof (int); #endif rc = zmq_getsockopt (bowl, ZMQ_FD, &fd, &fd_size); assert (rc == 0); rc = zmq_poller_add_fd (poller, fd, bowl); assert (rc == 0); rc = zmq_poller_wait (poller, &event, 500); assert (rc == 0); assert (event.socket == NULL); assert (event.fd == fd); assert (event.user_data == bowl); zmq_poller_remove_fd (poller, fd); // Polling on thread safe sockets zmq_poller_add_socket (poller, server, NULL); rc = zmq_connect (client, "tcp://127.0.0.1:55557"); assert (rc == 0); rc = zmq_send_const (client, data, 1, 0); assert (rc == 1); rc = zmq_poller_wait (poller, &event, 500); assert (rc == 0); assert (event.socket == server); assert (event.user_data == NULL); rc = zmq_recv (server, data, 1, 0); assert (rc == 1); // Destory poller, sockets and ctx rc = zmq_poller_close (poller); assert (rc == 0); rc = zmq_close (sink); assert (rc == 0); rc = zmq_close (vent); assert (rc == 0); rc = zmq_close (bowl); assert (rc == 0); rc = zmq_close (server); assert (rc == 0); rc = zmq_close (client); assert (rc == 0); rc = zmq_ctx_shutdown (ctx); assert (rc == 0); return 0; }
int main (void) { size_t len = MAX_SOCKET_STRING; char my_endpoint_0[MAX_SOCKET_STRING]; char my_endpoint_1[MAX_SOCKET_STRING]; setup_test_environment (); void *ctx = zmq_ctx_new (); assert (ctx); // Create few sockets void *vent = zmq_socket (ctx, ZMQ_PUSH); assert (vent); int rc = zmq_bind (vent, "tcp://127.0.0.1:*"); assert (rc == 0); rc = zmq_getsockopt (vent, ZMQ_LAST_ENDPOINT, my_endpoint_0, &len); assert (rc == 0); void *sink = zmq_socket (ctx, ZMQ_PULL); assert (sink); rc = zmq_connect (sink, my_endpoint_0); assert (rc == 0); void *bowl = zmq_socket (ctx, ZMQ_PULL); assert (bowl); #if defined(ZMQ_SERVER) && defined(ZMQ_CLIENT) void *server = zmq_socket (ctx, ZMQ_SERVER); assert (server); rc = zmq_bind (server, "tcp://127.0.0.1:*"); assert (rc == 0); len = MAX_SOCKET_STRING; rc = zmq_getsockopt (server, ZMQ_LAST_ENDPOINT, my_endpoint_1, &len); assert (rc == 0); void *client = zmq_socket (ctx, ZMQ_CLIENT); assert (client); #endif // Set up poller void *poller = zmq_poller_new (); zmq_poller_event_t event; // waiting on poller with no registered sockets should report error rc = zmq_poller_wait (poller, &event, 0); assert (rc == -1); assert (errno == EAGAIN); // register sink rc = zmq_poller_add (poller, sink, sink, ZMQ_POLLIN); assert (rc == 0); // Send a message char data[1] = {'H'}; rc = zmq_send_const (vent, data, 1, 0); assert (rc == 1); // We expect a message only on the sink rc = zmq_poller_wait (poller, &event, -1); assert (rc == 0); assert (event.socket == sink); assert (event.user_data == sink); rc = zmq_recv (sink, data, 1, 0); assert (rc == 1); // We expect timed out rc = zmq_poller_wait (poller, &event, 0); assert (rc == -1); assert (errno == EAGAIN); // Stop polling sink rc = zmq_poller_remove (poller, sink); assert (rc == 0); // Check we can poll an FD rc = zmq_connect (bowl, my_endpoint_0); assert (rc == 0); fd_t fd; size_t fd_size = sizeof (fd); rc = zmq_getsockopt (bowl, ZMQ_FD, &fd, &fd_size); assert (rc == 0); rc = zmq_poller_add_fd (poller, fd, bowl, ZMQ_POLLIN); assert (rc == 0); rc = zmq_poller_wait (poller, &event, 500); assert (rc == 0); assert (event.socket == NULL); assert (event.fd == fd); assert (event.user_data == bowl); zmq_poller_remove_fd (poller, fd); #if defined(ZMQ_SERVER) && defined(ZMQ_CLIENT) // Polling on thread safe sockets rc = zmq_poller_add (poller, server, NULL, ZMQ_POLLIN); assert (rc == 0); rc = zmq_connect (client, my_endpoint_1); assert (rc == 0); rc = zmq_send_const (client, data, 1, 0); assert (rc == 1); rc = zmq_poller_wait (poller, &event, 500); assert (rc == 0); assert (event.socket == server); assert (event.user_data == NULL); rc = zmq_recv (server, data, 1, 0); assert (rc == 1); // Polling on pollout rc = zmq_poller_modify (poller, server, ZMQ_POLLOUT | ZMQ_POLLIN); assert (rc == 0); rc = zmq_poller_wait (poller, &event, 0); assert (rc == 0); assert (event.socket == server); assert (event.user_data == NULL); assert (event.events == ZMQ_POLLOUT); // Stop polling server rc = zmq_poller_remove (poller, server); assert (rc == 0); #endif // Destroy sockets, poller and ctx rc = zmq_close (sink); assert (rc == 0); rc = zmq_close (vent); assert (rc == 0); rc = zmq_close (bowl); assert (rc == 0); #if defined(ZMQ_SERVER) && defined(ZMQ_CLIENT) rc = zmq_close (server); assert (rc == 0); rc = zmq_close (client); assert (rc == 0); #endif test_null_poller_pointers (ctx); test_null_socket_pointers (); test_null_event_pointers (ctx); test_add_modify_remove_corner_cases (ctx); test_wait_corner_cases (); rc = zmq_poller_destroy (&poller); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); return 0; }
/* EXPECTED ARGUMENTS: * <endpoint> <identity> */ int main(int argc, char *argv[]) { if (argc < 3) { fprintf(stderr, "Usage: testdriver <endpoint> <identity>\n"); return 1; } void *context = zmq_ctx_new(); void *socket = zmq_socket(context, ZMQ_DEALER); char *address = argv[1]; char *identity = argv[2]; fprintf(stdout, "Connecting worker %s to socket at %s\n", identity, address); zmq_setsockopt(socket, ZMQ_IDENTITY, identity, strlen(identity)); zmq_connect(socket, address); zmq_send_const(socket, "RDY", 3, 0); char *outbuffer = NULL; msgpack_unpacked unpacked; for (;;) { zmq_msg_t msg; zmq_msg_init(&msg); zmq_msg_recv(&msg, socket, 0); size_t size = zmq_msg_size(&msg); char *inbuffer = (char *) malloc(size + 1); if (NULL == inbuffer) { fprintf(stderr, "Out of Memory!\n"); return 1; } memcpy(inbuffer, zmq_msg_data(&msg), size); zmq_msg_close(&msg); inbuffer[size] = 0; msgpack_unpacked_init(&unpacked); size_t off = 0; bool res = msgpack_unpack_next(&unpacked, inbuffer, size, &off); if (!res) { fprintf(stderr,"res == %d\n", res); fprintf(stderr,"off == %zu\n", off); return 1; } msgpack_object obj = unpacked.data; uint32_t id = (uint32_t) obj.via.u64; msgpack_unpacked_destroy(&unpacked); res = msgpack_unpack_next(&unpacked, inbuffer, size, &off); if (!res) { fprintf(stderr, "res == %d\n", res); fprintf(stderr, "off == %zu\n", off); return 1; } obj = unpacked.data; const char* path = obj.via.str.ptr; PIN_SCORE_START(outbuffer); // TODO call sut here with path msgpack_unpacked_destroy(&unpacked); free(inbuffer); outbuffer = PIN_SCORE_END(id, socket); } }
int test_unsubscribe_cleanup (void) { size_t len = MAX_SOCKET_STRING; char my_endpoint[MAX_SOCKET_STRING]; void *ctx = zmq_ctx_new (); assert (ctx); // Create a publisher void *pub = zmq_socket (ctx, ZMQ_XPUB); assert (pub); int manual = 1; int rc = zmq_setsockopt (pub, ZMQ_XPUB_MANUAL, &manual, 4); assert (rc == 0); rc = zmq_bind (pub, "tcp://127.0.0.1:*"); assert (rc == 0); rc = zmq_getsockopt (pub, ZMQ_LAST_ENDPOINT, my_endpoint, &len); assert (rc == 0); // Create a subscriber void *sub = zmq_socket (ctx, ZMQ_XSUB); assert (sub); rc = zmq_connect (sub, my_endpoint); assert (rc == 0); // Subscribe for A char subscription[2] = {1, 'A'}; rc = zmq_send_const (sub, subscription, 2, 0); assert (rc == 2); char buffer[2]; // Receive subscriptions from subscriber rc = zmq_recv (pub, buffer, 2, 0); assert (rc == 2); assert (buffer[0] == 1); assert (buffer[1] == 'A'); rc = zmq_setsockopt (pub, ZMQ_SUBSCRIBE, "XA", 2); assert (rc == 0); // send 2 messages rc = zmq_send_const (pub, "XA", 2, 0); assert (rc == 2); rc = zmq_send_const (pub, "XB", 2, 0); assert (rc == 2); // receive the single message rc = zmq_recv (sub, buffer, 2, 0); assert (rc == 2); assert (buffer[0] == 'X'); assert (buffer[1] == 'A'); // should be nothing left in the queue rc = zmq_recv (sub, buffer, 2, ZMQ_DONTWAIT); assert (rc == -1); // close the socket rc = zmq_close (sub); assert (rc == 0); // closing the socket will result in an unsubscribe event rc = zmq_recv (pub, buffer, 2, 0); assert (rc == 2); assert (buffer[0] == 0); assert (buffer[1] == 'A'); // this doesn't really do anything // there is no last_pipe set it will just fail silently rc = zmq_setsockopt (pub, ZMQ_UNSUBSCRIBE, "XA", 2); assert (rc == 0); // reconnect sub = zmq_socket (ctx, ZMQ_XSUB); rc = zmq_connect (sub, my_endpoint); assert (rc == 0); // send a subscription for B subscription[0] = 1; subscription[1] = 'B'; rc = zmq_send (sub, subscription, 2, 0); assert (rc == 2); // receive the subscription, overwrite it to XB rc = zmq_recv (pub, buffer, 2, 0); assert (rc == 2); assert (buffer[0] == 1); assert (buffer[1] == 'B'); rc = zmq_setsockopt (pub, ZMQ_SUBSCRIBE, "XB", 2); assert (rc == 0); // send 2 messages rc = zmq_send_const (pub, "XA", 2, 0); assert (rc == 2); rc = zmq_send_const (pub, "XB", 2, 0); assert (rc == 2); // receive the single message rc = zmq_recv (sub, buffer, 2, 0); assert (rc == 2); assert (buffer[0] == 'X'); assert (buffer[1] == 'B'); // this assertion will fail // should be nothing left in the queue rc = zmq_recv (sub, buffer, 2, ZMQ_DONTWAIT); assert (rc == -1); // Clean up. rc = zmq_close (pub); assert (rc == 0); rc = zmq_close (sub); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); return 0; }
int main (void) { setup_test_environment(); void *ctx = zmq_ctx_new (); assert (ctx); void *client = zmq_socket (ctx, ZMQ_CLIENT); void *client2 = zmq_socket (ctx, ZMQ_CLIENT); int rc; rc = zmq_bind (client, "tcp://127.0.0.1:5560"); assert (rc == 0); rc = zmq_connect (client2, "tcp://127.0.0.1:5560"); assert (rc == 0); void* t1 = zmq_threadstart(worker1, client2); void* t2 = zmq_threadstart(worker2, client2); char data[1]; data[0] = 0; for (int i=0; i < 10; i++) { rc = zmq_send_const(client, data, 1, 0); assert (rc == 1); rc = zmq_send_const(client, data, 1, 0); assert(rc == 1); char a, b; rc = zmq_recv(client, &a, 1, 0); assert(rc == 1); rc = zmq_recv(client, &b, 1, 0); assert(rc == 1); // make sure they came from different threads assert((a == 1 && b == 2) || (a == 2 && b == 1)); } // make the thread exit data[0] = 1; rc = zmq_send_const(client, data, 1, 0); assert (rc == 1); rc = zmq_send_const(client, data, 1, 0); assert(rc == 1); zmq_threadclose(t1); zmq_threadclose(t2); rc = zmq_close (client2); assert (rc == 0); rc = zmq_close (client); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); return 0 ; }
int test_unsubscribe_manual() { void *ctx = zmq_ctx_new (); assert (ctx); // Create a publisher void *pub = zmq_socket (ctx, ZMQ_XPUB); assert (pub); int rc = zmq_bind (pub, "inproc://soname"); assert (rc == 0); // set pub socket options int manual = 1; rc = zmq_setsockopt(pub, ZMQ_XPUB_MANUAL, &manual, 4); assert (rc == 0); // Create a subscriber void *sub = zmq_socket (ctx, ZMQ_XSUB); assert (sub); rc = zmq_connect (sub, "inproc://soname"); assert (rc == 0); // Subscribe for A char subscription1[2] = { 1, 'A'}; rc = zmq_send_const(sub, subscription1, 2, 0); assert (rc == 2); // Subscribe for B char subscription2[2] = { 1, 'B'}; rc = zmq_send_const(sub, subscription2, 2, 0); assert (rc == 2); char buffer[3]; // Receive subscription "A" from subscriber rc = zmq_recv(pub, buffer, 2, 0); assert(rc == 2); assert(buffer[0] == 1); assert(buffer[1] == 'A'); // Subscribe socket for XA instead rc = zmq_setsockopt(pub, ZMQ_SUBSCRIBE, "XA", 2); assert(rc == 0); // Receive subscription "B" from subscriber rc = zmq_recv(pub, buffer, 2, 0); assert(rc == 2); assert(buffer[0] == 1); assert(buffer[1] == 'B'); // Subscribe socket for XB instead rc = zmq_setsockopt(pub, ZMQ_SUBSCRIBE, "XB", 2); assert(rc == 0); // Unsubscribe from A char unsubscription1[2] = { 0, 'A'}; rc = zmq_send_const(sub, unsubscription1, 2, 0); assert (rc == 2); // Receive unsubscription "A" from subscriber rc = zmq_recv(pub, buffer, 2, 0); assert(rc == 2); assert(buffer[0] == 0); assert(buffer[1] == 'A'); // Unsubscribe socket from XA instead rc = zmq_setsockopt(pub, ZMQ_UNSUBSCRIBE, "XA", 2); assert(rc == 0); // Sending messages XA, XB rc = zmq_send_const(pub, "XA", 2, 0); assert(rc == 2); rc = zmq_send_const(pub, "XB", 2, 0); assert(rc == 2); // Subscriber should receive XB only rc = zmq_recv(sub, buffer, 2, ZMQ_DONTWAIT); assert(rc == 2); assert(buffer[0] == 'X'); assert(buffer[1] == 'B'); // Close subscriber rc = zmq_close (sub); assert (rc == 0); // Receive unsubscription "B" rc = zmq_recv(pub, buffer, 2, 0); assert(rc == 2); assert(buffer[0] == 0); assert(buffer[1] == 'B'); // Unsubscribe socket from XB instead rc = zmq_setsockopt(pub, ZMQ_UNSUBSCRIBE, "XB", 2); assert(rc == 0); // Clean up. rc = zmq_close (pub); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); return 0 ; }
/** * Send an empty (zero-length) frame * @param socket The socket to send data over * @param flags The send flags, e.g. ZMQ_SNDMORE * @return -1 on error (you can check errno to get more information), 0 on success */ static inline int sendEmptyFrame(void* socket, int flags = 0) { return (zmq_send_const (socket, nullptr, 0, flags) == -1); }
int main (void) { setup_test_environment (); void *ctx = zmq_ctx_new (); assert (ctx); // Create few sockets void *vent = zmq_socket (ctx, ZMQ_PUSH); assert (vent); int rc = zmq_bind (vent, "tcp://127.0.0.1:55556"); assert (rc == 0); void *sink = zmq_socket (ctx, ZMQ_PULL); assert (sink); rc = zmq_connect (sink, "tcp://127.0.0.1:55556"); assert (rc == 0); void *bowl = zmq_socket (ctx, ZMQ_PULL); assert (bowl); #if defined(ZMQ_SERVER) && defined(ZMQ_CLIENT) void *server = zmq_socket (ctx, ZMQ_SERVER); assert (server); rc = zmq_bind (server, "tcp://127.0.0.1:55557"); assert (rc == 0); void *client = zmq_socket (ctx, ZMQ_CLIENT); assert (client); #endif // Set up poller void* poller = zmq_poller_new (); zmq_poller_event_t event; // waiting on poller with no registered sockets should report error rc = zmq_poller_wait(poller, &event, 0); assert (rc == -1); assert (errno == ETIMEDOUT); // register sink rc = zmq_poller_add (poller, sink, sink, ZMQ_POLLIN); assert (rc == 0); // Send a message char data[1] = {'H'}; rc = zmq_send_const (vent, data, 1, 0); assert (rc == 1); // We expect a message only on the sink rc = zmq_poller_wait (poller, &event, -1); assert (rc == 0); assert (event.socket == sink); assert (event.user_data == sink); rc = zmq_recv (sink, data, 1, 0); assert (rc == 1); // We expect timed out rc = zmq_poller_wait (poller, &event, 0); assert (rc == -1); assert (errno == ETIMEDOUT); // Stop polling sink rc = zmq_poller_remove (poller, sink); assert (rc == 0); // Check we can poll an FD rc = zmq_connect (bowl, "tcp://127.0.0.1:55556"); assert (rc == 0); #if defined _WIN32 SOCKET fd; size_t fd_size = sizeof (SOCKET); #else int fd; size_t fd_size = sizeof (int); #endif rc = zmq_getsockopt (bowl, ZMQ_FD, &fd, &fd_size); assert (rc == 0); rc = zmq_poller_add_fd (poller, fd, bowl, ZMQ_POLLIN); assert (rc == 0); rc = zmq_poller_wait (poller, &event, 500); assert (rc == 0); assert (event.socket == NULL); assert (event.fd == fd); assert (event.user_data == bowl); zmq_poller_remove_fd (poller, fd); #if defined(ZMQ_SERVER) && defined(ZMQ_CLIENT) // Polling on thread safe sockets rc = zmq_poller_add (poller, server, NULL, ZMQ_POLLIN); assert (rc == 0); rc = zmq_connect (client, "tcp://127.0.0.1:55557"); assert (rc == 0); rc = zmq_send_const (client, data, 1, 0); assert (rc == 1); rc = zmq_poller_wait (poller, &event, 500); assert (rc == 0); assert (event.socket == server); assert (event.user_data == NULL); rc = zmq_recv (server, data, 1, 0); assert (rc == 1); // Polling on pollout rc = zmq_poller_modify (poller, server, ZMQ_POLLOUT | ZMQ_POLLIN); assert (rc == 0); rc = zmq_poller_wait (poller, &event, 0); assert (rc == 0); assert (event.socket == server); assert (event.user_data == NULL); assert (event.events == ZMQ_POLLOUT); #endif // Destory sockets, poller and ctx rc = zmq_close (sink); assert (rc == 0); rc = zmq_close (vent); assert (rc == 0); rc = zmq_close (bowl); assert (rc == 0); #if defined(ZMQ_SERVER) && defined(ZMQ_CLIENT) rc = zmq_close (server); assert (rc == 0); rc = zmq_close (client); assert (rc == 0); #endif // Test error - null poller pointers rc = zmq_poller_destroy (NULL); assert (rc == -1 && errno == EFAULT); void *null_poller = NULL; rc = zmq_poller_destroy (&null_poller); assert (rc == -1 && errno == EFAULT); rc = zmq_poller_destroy (&poller); assert(rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); return 0; }
void test_router_2_router(bool named){ void *rbind, *rconn1; int ret; char buff[256]; char msg[] = "hi 1"; const char *bindip = "tcp://127.0.0.1:5556"; int zero = 0; void *ctx = zmq_ctx_new (); // Create bind socket. rbind = zmq_socket (ctx, ZMQ_ROUTER); assert (rbind); ret = zmq_setsockopt (rbind, ZMQ_LINGER, &zero, sizeof (zero)); assert (0 == ret); ret = zmq_bind (rbind, bindip); assert (0 == ret); // Create connection socket. rconn1 = zmq_socket (ctx, ZMQ_ROUTER); assert (rconn1); ret = zmq_setsockopt (rconn1, ZMQ_LINGER, &zero, sizeof (zero)); assert (0 == ret); // If we're in named mode, set some identities. if (named) { ret = zmq_setsockopt (rbind, ZMQ_IDENTITY, "X", 1); ret = zmq_setsockopt (rconn1, ZMQ_IDENTITY, "Y", 1); } // Make call to connect using a connect_rid. ret = zmq_setsockopt (rconn1, ZMQ_CONNECT_RID, "conn1", 6); assert (0 == ret); ret = zmq_connect (rconn1, bindip); assert (0 == ret); /* Uncomment to test assert on duplicate rid // Test duplicate connect attempt. ret = zmq_setsockopt (rconn1, ZMQ_CONNECT_RID, "conn1", 6); assert (0 == ret); ret = zmq_connect (rconn1, bindip); assert (0 == ret); */ // Send some data. ret = zmq_send (rconn1, "conn1", 6, ZMQ_SNDMORE); assert (6 == ret); ret = zmq_send (rconn1, msg, 5, 0); assert (5 == ret); // Receive the name. ret = zmq_recv (rbind, buff, 256, 0); if (named) assert (ret && 'Y' == buff[0]); else assert (ret && 0 == buff[0]); // Receive the data. ret = zmq_recv (rbind, buff+128, 128, 0); assert(5 == ret && 'h' == buff[128]); // Send some data back. if (named) { ret = zmq_send (rbind, buff, 1, ZMQ_SNDMORE); assert (1 == ret); } else { ret = zmq_send (rbind, buff, 5, ZMQ_SNDMORE); assert (5 == ret); } ret = zmq_send_const (rbind, "ok", 3, 0); assert (3 == ret); // If bound socket identity naming a problem, we'll likely see something funky here. ret = zmq_recv (rconn1, buff, 256, 0); assert ('c' == buff[0] && 6 == ret); ret = zmq_recv (rconn1, buff+128, 128, 0); assert (3 == ret && 'o' == buff[128]); ret = zmq_unbind (rbind, bindip); assert(0 == ret); ret = zmq_close (rbind); assert(0 == ret); ret = zmq_close (rconn1); assert(0 == ret); zmq_ctx_destroy (ctx); }