Skip to content

Instantly share code, notes, and snippets.

@brettviren
Created January 17, 2020 00:12
Show Gist options
  • Save brettviren/dde42c6f1c8078c07e0ce595dd619919 to your computer and use it in GitHub Desktop.
Save brettviren/dde42c6f1c8078c07e0ce595dd619919 to your computer and use it in GitHub Desktop.
/*
$ gcc -o issue3596 issue3596.c -Wl,-rpath $HOME/opt/zmq/lib -I$HOME/opt/zmq/include -L$HOME/opt/zmq/lib -lzmq -lpthread
$ ./issue3596
client
client
client
...forever and ever...
*/
#define ZMQ_BUILD_DRAFT_API
#include <zmq.h>
#include <pthread.h>
#include <unistd.h>
#include <assert.h>
typedef unsigned int uint32_t;
typedef struct {
uint32_t rid;
void* server;
} server_data_t;
static void* server_func(void* varg)
{
server_data_t* sd = (server_data_t*)varg;
uint32_t rid = sd->rid;
void* server = sd->server;
while(1) {
zmq_msg_t msg;
zmq_msg_init(&msg);
int rc = zmq_msg_set_routing_id(&msg, rid);
assert(rc == 0);
rc = zmq_msg_send(&msg, server, 0);
assert(rc == 0);
}
}
static void* client_func(void* client)
{
while(1) {
zmq_msg_t msg;
int rc = zmq_msg_recv(&msg, client, 0);
assert(rc);
sleep(3);
printf("client\n");
}
}
int main()
{
void *ctx = zmq_ctx_new();
/* Create a CLIENT and SERVER socket and connect them to each
* other via TCP. */
void *client = zmq_socket(ctx, ZMQ_CLIENT);
void *server = zmq_socket(ctx, ZMQ_SERVER);
const char* addr = "tcp://127.0.0.1:5678";
int rc = zmq_bind (server, addr);
assert (rc == 0);
rc = zmq_connect(client, addr);
assert (rc == 0);
/* Set the CLIENT's heartbeat interval to 1 second and its
* recv high water mark to 1. */
int onesec = 1000;
rc = zmq_setsockopt(client, ZMQ_HEARTBEAT_IVL, &onesec, sizeof(onesec));
assert (rc == 0);
int one = 1;
rc = zmq_setsockopt(client, ZMQ_RCVHWM, &one, sizeof(one));
assert (rc == 0);
/* Send an empty message from the CLIENT to the SERVER and
* retrieve the routing id of the CLIENT. */
zmq_msg_t msg;
zmq_msg_init(&msg);
rc = zmq_msg_send(&msg, client, 0);
assert (rc == 0);
rc = zmq_msg_recv(&msg, server, 0);
assert (rc != -1);
uint32_t rid = zmq_msg_routing_id(&msg);
assert (rid > 0);
/* Move the SERVER to a new thread and send empty messages to
* the CLIENT using the routing id in a loop. */
pthread_t server_worker;
server_data_t server_data;
server_data.rid = rid;
server_data.server = server;
pthread_create (&server_worker, NULL, server_func, &server_data);
/* Now create a loop for the CLIENT where it receives a message
* then waits 3 seconds after receiving each message to
* simulate a slow client. */
pthread_t client_worker;
pthread_create (&client_worker, NULL, client_func, client);
/* this runs forever */
pthread_join(client_worker, NULL);
pthread_join(server_worker, NULL);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment