static void s_socket_event (agent_t *self) { // First frame is event number and value zframe_t *frame = zframe_recv (self->socket); int event = *(uint16_t *) (zframe_data (frame)); int value = *(uint32_t *) (zframe_data (frame) + 2); zframe_destroy (&frame); // Second frame is address char *address = zstr_recv (self->socket); char *description = "Unknown"; switch (event) { case ZMQ_EVENT_ACCEPTED: description = "Accepted"; break; case ZMQ_EVENT_ACCEPT_FAILED: description = "Accept failed"; break; case ZMQ_EVENT_BIND_FAILED: description = "Bind failed"; break; case ZMQ_EVENT_CLOSED: description = "Closed"; break; case ZMQ_EVENT_CLOSE_FAILED: description = "Close failed"; break; case ZMQ_EVENT_DISCONNECTED: description = "Disconnected"; break; case ZMQ_EVENT_CONNECTED: description = "Connected"; break; case ZMQ_EVENT_CONNECT_DELAYED: description = "Connect delayed"; break; case ZMQ_EVENT_CONNECT_RETRIED: description = "Connect retried"; break; case ZMQ_EVENT_LISTENING: description = "Listening"; break; case ZMQ_EVENT_MONITOR_STOPPED: description = "Monitor stopped"; break; default: zsys_error ("illegal socket monitor event: %d", event); break; } if (self->verbose) zsys_info ("zmonitor: %s - %s\n", description, address); zstr_sendfm (self->pipe, "%d", event); zstr_sendfm (self->pipe, "%d", value); zstr_sendm (self->pipe, address); zstr_send (self->pipe, description); free (address); }
curve_client_t * curve_client_new (zcert_t **cert_p) { curve_client_t *self = (curve_client_t *) zmalloc (sizeof (curve_client_t)); assert (self); self->ctx = zctx_new (); self->control = zthread_fork (self->ctx, s_agent_task, NULL); // Create separate data socket, send address on control socket self->data = zsocket_new (self->ctx, ZMQ_PAIR); assert (self->data); int rc = zsocket_bind (self->data, "inproc://data-%p", self->data); assert (rc != -1); zstr_sendfm (self->control, "inproc://data-%p", self->data); // Now send cert on control socket as well rc = zmq_send (self->control, zcert_public_key (*cert_p), 32, ZMQ_SNDMORE); assert (rc == 32); rc = zmq_send (self->control, zcert_secret_key (*cert_p), 32, 0); assert (rc == 32); zcert_destroy (cert_p); return self; }
void fmq_server_publish (fmq_server_t *self, const char *location, const char *alias) { assert (self); assert (location); assert (alias); zstr_sendm (self->pipe, "PUBLISH"); zstr_sendfm (self->pipe, "%s", location); zstr_sendf (self->pipe, "%s", alias); }
int main (void) { zctx_t *ctx = zctx_new (); void *dealer = zsocket_new (ctx, ZMQ_DEALER); zsocket_connect (dealer, "tcp://127.0.0.1:6000"); // We'll allow up to N chunks in transit at once size_t credit = PIPELINE; size_t total = 0; // Total bytes received size_t chunks = 0; // Total chunks received size_t offset = 0; // Offset of next chunk request size_t offset_expc = 0; while (true) { while (credit) { // Ask for next chunk zstr_sendfm (dealer, "fetch"); zstr_sendfm (dealer, "%ld", offset); zstr_sendf (dealer, "%ld", CHUNK_SIZE); offset += CHUNK_SIZE; credit--; } zframe_t *chunk = zframe_recv (dealer); if (!chunk) break; // Shutting down, quit chunks++; credit++; size_t size = zframe_size (chunk); zframe_destroy (&chunk); total += size; if (size < CHUNK_SIZE) break; // Last chunk received; exit } printf ("%zd chunks received, %zd bytes\n", chunks, total); zctx_destroy (&ctx); return total == 102400? 0: -1; }
static void s_self_handle_sink (self_t *self) { #if defined (ZMQ_EVENT_ALL) #if (ZMQ_VERSION_MAJOR == 4) // First frame is event number and value zframe_t *frame = zframe_recv (self->sink); int event = *(uint16_t *) (zframe_data (frame)); int value = *(uint32_t *) (zframe_data (frame) + 2); // Address is in second message frame char *address = zstr_recv (self->sink); zframe_destroy (&frame); #elif (ZMQ_VERSION_MAJOR == 3 && ZMQ_VERSION_MINOR == 2) // zmq_event_t is passed as-is in the frame zframe_t *frame = zframe_recv (self->sink); zmq_event_t *eptr = (zmq_event_t *) zframe_data (frame); int event = eptr->event; int value = eptr->data.listening.fd; char *address = strdup (eptr->data.listening.addr); assert (address); zframe_destroy (&frame); #else // We can't plausibly be here with other versions of libzmq assert (false); #endif // Now map event to text equivalent char *name; switch (event) { case ZMQ_EVENT_ACCEPTED: name = "ACCEPTED"; break; case ZMQ_EVENT_ACCEPT_FAILED: name = "ACCEPT_FAILED"; break; case ZMQ_EVENT_BIND_FAILED: name = "BIND_FAILED"; break; case ZMQ_EVENT_CLOSED: name = "CLOSED"; break; case ZMQ_EVENT_CLOSE_FAILED: name = "CLOSE_FAILED"; break; case ZMQ_EVENT_DISCONNECTED: name = "DISCONNECTED"; break; case ZMQ_EVENT_CONNECTED: name = "CONNECTED"; break; case ZMQ_EVENT_CONNECT_DELAYED: name = "CONNECT_DELAYED"; break; case ZMQ_EVENT_CONNECT_RETRIED: name = "CONNECT_RETRIED"; break; case ZMQ_EVENT_LISTENING: name = "LISTENING"; break; #if (ZMQ_VERSION_MAJOR == 4) case ZMQ_EVENT_MONITOR_STOPPED: name = "MONITOR_STOPPED"; break; #endif default: zsys_error ("illegal socket monitor event: %d", event); name = "UNKNOWN"; break; } if (self->verbose) zsys_info ("zmonitor: %s - %s", name, address); zstr_sendfm (self->pipe, "%s", name); zstr_sendfm (self->pipe, "%d", value); zstr_send (self->pipe, address); free (address); #endif }
/// // Send a formatted string to a socket, as for zstr_sendf(), with a // MORE flag, so that you can send further strings in the same multi-part // message. int QmlZstrAttached::sendfm (void *dest, const QString &format) { return zstr_sendfm (dest, "%s", format.toUtf8().data()); };
int main (int argn, char *argv []) { // Raise theoretical limit on how many ZeroMQ sockets we can create, // though real limit will be set by the process file handle limit. zsys_set_max_sockets (65535); // Test case 1: two servers, bunch of clients. printf ("Starting small test case: "); fflush (stdout); zactor_t *server1 = zactor_new (zgossip, "server1"); assert (server1); zstr_sendx (server1, "SET", "server/animate", "0", NULL); zstr_sendx (server1, "BIND", "inproc://server1", NULL); zactor_t *server2 = zactor_new (zgossip, "server2"); assert (server2); zstr_sendx (server2, "SET", "server/animate", "0", NULL); zstr_sendx (server2, "BIND", "inproc://server2", NULL); zstr_sendx (server2, "CONNECT", "inproc://server1", NULL); zactor_t *client1 = zactor_new (zgossip, "client1"); assert (client1); zstr_sendx (client1, "BIND", "inproc://client1", NULL); zstr_sendx (client1, "PUBLISH", "client1-00", "0000", NULL); zstr_sendx (client1, "PUBLISH", "client1-11", "1111", NULL); zstr_sendx (client1, "PUBLISH", "client1-22", "2222", NULL); zstr_sendx (client1, "CONNECT", "inproc://server1", NULL); zactor_t *client2 = zactor_new (zgossip, "client2"); assert (client2); zstr_sendx (client2, "BIND", "inproc://client2", NULL); zstr_sendx (client2, "CONNECT", "inproc://server1", NULL); zstr_sendx (client2, "PUBLISH", "client2-00", "0000", NULL); zstr_sendx (client2, "PUBLISH", "client2-11", "1111", NULL); zstr_sendx (client2, "PUBLISH", "client2-22", "2222", NULL); zactor_t *client3 = zactor_new (zgossip, "client3"); assert (client3); zstr_sendx (client3, "CONNECT", "inproc://server2", NULL); zactor_t *client4 = zactor_new (zgossip, "client4"); assert (client4); zstr_sendx (client4, "CONNECT", "inproc://server2", NULL); zclock_sleep (100); assert_status (server1, 6); assert_status (server2, 6); assert_status (client1, 6); assert_status (client2, 6); assert_status (client3, 6); assert_status (client4, 6); zactor_destroy (&server1); zactor_destroy (&server2); zactor_destroy (&client1); zactor_destroy (&client2); zactor_destroy (&client3); zactor_destroy (&client4); printf ("OK\n"); // Test case 2: swarm of peers printf ("Starting swarm test case: "); fflush (stdout); // Default limit on file handles is 1024 (POSIX), and fixed setup // costs 8 handles (3 standard I/O plus 5 for CZMQ/libzmq). So the // most nodes we can test by default is (1024 - 8) / 4 = 254. To // test more, run "ulimit -n xxx" beforehand and pass swarm size // as argument to this program. With e.g. Ubuntu, ceiling is 4K // file handles per process, so the largest swarm I've tested is // 1022 nodes. int swarm_size = 254; if (argn >= 2) swarm_size = atoi (argv [1]); printf ("swarm_size=%d ", swarm_size); // The set size defines the total number of properties we spread // across the swarm. By default this is the swarm_size * 5. You can // specify a different set size as second command line argument. int set_size = swarm_size * 5; if (argn >= 3) set_size = atoi (argv [2]); printf ("set_size=%d ", set_size); // Swarm is an array of actors zactor_t *nodes [swarm_size]; // We'll poll all actors for activity (actors act like sockets) zpoller_t *poller = zpoller_new (NULL); assert (poller); // Create swarm uint node_nbr; for (node_nbr = 0; node_nbr < swarm_size; node_nbr++) { nodes [node_nbr] = zactor_new (zgossip, NULL); assert (nodes [node_nbr]); zpoller_add (poller, nodes [node_nbr]); } printf ("."); fflush (stdout); // Interconnect swarm; ever node connects to one arbitrary node to // create a directed graph, then oldest node connects to youngest // node to create a loop, to test we're robust against cycles. for (node_nbr = 0; node_nbr < swarm_size; node_nbr++) { zstr_sendm (nodes [node_nbr], "BIND"); zstr_sendf (nodes [node_nbr], "inproc://swarm-%d", node_nbr); if (node_nbr > 0) { zstr_sendm (nodes [node_nbr], "CONNECT"); zstr_sendf (nodes [node_nbr], "inproc://swarm-%d", randof (node_nbr)); } } zstr_sendm (nodes [0], "CONNECT"); zstr_sendf (nodes [0], "inproc://swarm-%d", node_nbr - 1); printf ("."); fflush (stdout); // Publish the data set randomly across the swarm int item_nbr; for (item_nbr = 0; item_nbr < set_size; item_nbr++) { node_nbr = randof (swarm_size); assert (node_nbr != swarm_size); assert (node_nbr < swarm_size); zstr_sendm (nodes [node_nbr], "PUBLISH"); zstr_sendfm (nodes [node_nbr], "key-%d", item_nbr); zstr_send (nodes [node_nbr], "value"); } printf (". "); fflush (stdout); // Each actor will deliver us tuples; count these until we're done int total = set_size * swarm_size; int pending = total; int64_t ticker = zclock_mono () + 2000; while (pending) { zsock_t *which = (zsock_t *) zpoller_wait (poller, 100); if (!which) { puts (" - stuck test, aborting"); break; } char *command; zstr_recvx (which, &command, NULL); assert (streq (command, "DELIVER")); pending--; freen (command); if (zclock_mono () > ticker) { printf ("(%d%%)", (int) ((100 * (total - pending)) / total)); fflush (stdout); ticker = zclock_mono () + 2000; } } // Destroy swarm for (node_nbr = 0; node_nbr < swarm_size; node_nbr++) zactor_destroy (&nodes [node_nbr]); printf ("(100%%) OK\n"); #if defined (__WINDOWS__) zsys_shutdown(); #endif return 0; }
/// // Send a formatted string to a socket, as for zstr_sendf(), with a // MORE flag, so that you can send further strings in the same multi-part // message. int QZstr::sendfm (void *dest, const QString ¶m) { int rv = zstr_sendfm (dest, "%s", param.toUtf8().data()); return rv; }