zeromq pub/sub example in c (libzmq) - c

Can someone show me "Hello World" example for zeromq pub/sub in c using libzmq. I have done coding req/rep example It's well documented but I couldn't find good hello world example for pub/sub that works fine with me.
Here is my try.
pub.c
#include <zmq.h>
#include <string.h>
int main()
{
void *context = zmq_ctx_new();
void *publisher = zmq_socket(context, ZMQ_PUB);
zmq_bind(publisher, "tcp://127.0.0.1:5555");
char message[15] = "Hello World!";
while(1)
{
zmq_msg_t msg;
zmq_msg_init_size(&message, strlen(message));
memcpy(zmq_msg_data(&msg), message, strlen(message));
zmq_msg_send(publisher, &msg, 0);
zmq_msg_close(&msg);
}
zmq_close(publisher);
zmq_ctx_destroy(context);
return 0;
}
sub.c
#include <zmq.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
int main()
{
void *context = zmq_ctx_new();
void *subscriber = zmq_socket(context, ZMQ_SUB);
int rc = zmq_connect(subscriber, "tcp://127.0.0.1:5555");
assert(rc == 0);
zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0);
char message[15] = "";
while(1)
{
zmq_msg_t msg;
zmq_msg_init(&msg);
zmq_msg_recv(subscriber, &msg, 0);
int size = zmq_msg_size(&msg);
memcpy(message, zmq_msg_data(&msg), size);
zmq_msg_close(&msg);
printf("%s\n", message);
}
zmq_close(subscriber);
zmq_ctx_destroy(context);
return 0;
}
Thanks in advance

Finally this code works with me
pub.c
#include <stdio.h>
#include <assert.h>
#include <zmq.h>
int main()
{
void *context = zmq_ctx_new();
void *publisher = zmq_socket(context, ZMQ_PUB);
int rc = zmq_bind(publisher, "tcp://127.0.0.1:5556");
assert(rc == 0);
while(1)
{
rc = zmq_send(publisher, "Hello World!", 12, 0);
assert(rc == 12);
}
zmq_close(publisher);
zmq_ctx_destroy(context);
return 0;
}
sub.c
#include <stdio.h>
#include <assert.h>
#include <zmq.h>
int main()
{
void *context = zmq_ctx_new();
void *subscriber = zmq_socket(context, ZMQ_SUB);
int rc = zmq_connect(subscriber, "tcp://127.0.0.1:5556");
assert(rc == 0);
rc = zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0);
assert(rc == 0);
char message[12];
while(1)
{
rc = zmq_recv(subscriber, message, 12, 0);
assert(rc != -1);
printf("%s\n", message);
}
zmq_close(subscriber);
zmq_ctx_destroy(context);
return 0;
}

Related

ZeroMQ in request-replay pattern allow request comming from specific ip only

How to allow request coming from specific IP address only in 0MQ request-reply pattern.
I don't want to receive request from any other IP address. I want to communicate only between two IP address first one is request maker and second one is reply maker.
request.c
#include <zmq.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
int main(void) {
void *context = zmq_ctx_new();
void *requester = zmq_socket(context, ZMQ_REQ);
zmq_connect(requester, "tcp://127.0.0.1:5555");
char buffer[10];
printf ("Sending Hello\n");
zmq_send(requester, "Hello", 5, 0);
zmq_recv(requester, buffer, 10, 0);
printf("Received: %s\n", buffer);
zmq_close (requester);
zmq_ctx_destroy (context);
return 0;
}
reply.c
#include <zmq.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
int main(void) {
void *context = zmq_ctx_new();
void *responder = zmq_socket(context, ZMQ_REP);
int rc = zmq_bind(responder, "tcp://127.0.0.1:5555");
assert(rc == 0);
char buffer[10];
zmq_recv(responder, buffer, 10, 0);
printf("Recived: %s\n", buffer);
sleep(1);
zmq_send(responder, "World", 5, 0);
return 0;
}
From comments:
From stackoverflow.com/questions/20336954/0mq-get-message-ip it is
impossible. Do not use 0MQ and use other tool.

Get all output from sqlite3 in C

I have a table with 2 entry :
id hostname ip port
1 Raspberry pi 192.168.1.49 22
2 Test 127.0.0.1 22
In my code i get only the first entry with sqlite3.
I have :
{"id": "1", "hostname": "Raspberry pi", "ip": "192.168.1.49", "port": "22"}
Where is the second entry ?
I tried with printf and get the same problem it's not json issue.
There is the code :
#include <stdarg.h> /* va_list */
#include <stddef.h> /* NULL */
#include <stdint.h> /* int64_t */
#include <stdlib.h>
#include <string.h> /* memset */
#include <stdio.h>
#include <sqlite3.h>
#include <kcgi.h>
#include <kcgihtml.h>
#include <kcgijson.h>
static int callback(void *ptr, int argc, char **argv, char **azColName) {
struct kjsonreq *req = (struct kjsonreq *)ptr;
struct khtmlreq r;
int i;
for(i=0; i<argc; i++){
kjson_putstringp(req, azColName[i], argv[i] ? argv[i] : "NULL");
}
}
int
main(void)
{
struct kreq r;
struct kjsonreq req;
const char *page = "index";
if (khttp_parse(&r, NULL, 0, &page, 1, 0) != KCGI_OK)
return EXIT_FAILURE;
khttp_head(&r, kresps[KRESP_STATUS],
"%s", khttps[KHTTP_200]);
khttp_head(&r, kresps[KRESP_CONTENT_TYPE],
"%s", kmimetypes[r.mime]);
khttp_body(&r);
kjson_open(&req, &r);
kjson_obj_open(&req);
sqlite3 *db;
char *zErrMsg = 0;
int rc;
rc = sqlite3_open("/var/www/MaSSH/databases/massh.db", &db);
if(rc){
sqlite3_close(db);
}
rc = sqlite3_exec(db, "SELECT * FROM hosts;", callback, &req, &zErrMsg);
if(rc!= SQLITE_OK){
sqlite3_free(zErrMsg);
}
sqlite3_close(db);
kjson_obj_close(&req);
kjson_close(&req);
khttp_free(&r);
return EXIT_SUCCESS;
}
#include <sys/types.h> /* size_t, ssize_t */
#include <stdarg.h> /* va_list */
#include <stddef.h> /* NULL */
#include <stdint.h> /* int64_t */
#include <stdlib.h>
#include <string.h> /* memset */
#include <stdio.h>
#include <sqlite3.h>
#include <kcgi.h>
#include <kcgihtml.h>
#include <kcgijson.h>
int
main(void)
{
struct kreq r;
struct kjsonreq req;
const char *page = "index";
if (khttp_parse(&r, NULL, 0, &page, 1, 0) != KCGI_OK)
return EXIT_FAILURE;
khttp_head(&r, kresps[KRESP_STATUS],
"%s", khttps[KHTTP_200]);
khttp_head(&r, kresps[KRESP_CONTENT_TYPE],
"%s", kmimetypes[r.mime]);
khttp_body(&r);
kjson_open(&req, &r);
kjson_obj_open(&req);
sqlite3 *db;
sqlite3_stmt *res;
int rc;
rc = sqlite3_open("/var/www/MaSSH/databases/massh.db", &db);
if(rc){
sqlite3_close(db);
}
rc = sqlite3_prepare_v2(db, "SELECT * FROM hosts;", -1, &res, 0);
while((rc = sqlite3_step(res)) == SQLITE_ROW){
kjson_objp_open(&req, "host");
kjson_putstringp(&req, "id", sqlite3_column_text(res,0));
kjson_putstringp(&req, "hostname", sqlite3_column_text(res,1));
kjson_putstringp(&req, "ip", sqlite3_column_text(res,2));
kjson_putstringp(&req, "port", sqlite3_column_text(res,3));
kjson_obj_close(&req);
}
sqlite3_close(db);
kjson_obj_close(&req);
kjson_close(&req);
khttp_free(&r);
return EXIT_SUCCESS;
}

dbus c program - send(with reply) and receive using method_call

I'm new to D-Bus. I want a c program to send and receive data using the dbus_message_new_method_call function. I have tried the following programs from the link How to reply a D-Bus message but I'm getting error in the server.c side like "the name client.signal.Object was not provided by any .service files"
"server.c"
/* server.c */
#include <dbus/dbus.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
static DBusHandlerResult
filter_func(DBusConnection *connection, DBusMessage *message, void *usr_data)
{
DBusMessage *reply;
dbus_bool_t handled = false;
char *word = NULL;
DBusError dberr;
dbus_error_init(&dberr);
dbus_message_get_args(message, &dberr, DBUS_TYPE_STRING, &word, DBUS_TYPE_INVALID);
printf("receive message: %s\n", word);
handled = true;
reply = dbus_message_new_method_return(message);
char * reply_content;
printf("\nEnter your Reply Msg : ");
scanf("%s",reply_content);
dbus_message_append_args(reply, DBUS_TYPE_STRING, &reply_content, DBUS_TYPE_INVALID);
dbus_connection_send(connection, reply, NULL);
dbus_connection_flush(connection);
dbus_message_unref(reply);
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
}
int main(int argc, char *argv[])
{
DBusError dberr;
DBusConnection *dbconn;
dbus_error_init(&dberr);
dbconn = dbus_bus_get(DBUS_BUS_SESSION, &dberr);
if (!dbus_connection_add_filter(dbconn, filter_func, NULL, NULL))
{
return -1;
}
dbus_bus_add_match(dbconn, "type='method_call',interface='client.signal.Type'", &dberr);
while(dbus_connection_read_write_dispatch(dbconn, -1))
{
/* loop */
}
return 0;
}
here client.c
#include <dbus/dbus.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
static DBusHandlerResult
filter_func(DBusConnection *connection, DBusMessage *message, void *usr_data)
{
dbus_bool_t handled = false;
char *word = NULL;
DBusError dberr;
dbus_error_init(&dberr);
dbus_message_get_args(message, &dberr, DBUS_TYPE_STRING, &word, DBUS_TYPE_INVALID);
printf("receive message %s\n", word);
handled = true;
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
}
int db_send(DBusConnection *dbconn)
{
DBusMessage *dbmsg;
char *word = (char *)malloc(sizeof(char));
int i;
dbmsg = dbus_message_new_method_call("client.signal.Object","/client/signal/Object", "client.signal.Type", "Test");
scanf("%s", word);
if (!dbus_message_append_args(dbmsg, DBUS_TYPE_STRING, &word, DBUS_TYPE_INVALID))
{
return -1;
}
if (!dbus_connection_send(dbconn, dbmsg, NULL))
{
return -1;
}
dbus_connection_flush(dbconn);
printf("send message %s\n", word);
dbus_message_unref(dbmsg);
return 0;
}
int main(int argc, char *argv[])
{
DBusError dberr;
DBusConnection *dbconn;
dbus_error_init(&dberr);
dbconn = dbus_bus_get(DBUS_BUS_SESSION, &dberr);
if (!dbus_connection_add_filter(dbconn, filter_func, NULL, NULL))
{
return -1;
}
db_send(dbconn);
while(dbus_connection_read_write_dispatch(dbconn, -1))
{
db_send(dbconn);
}
dbus_connection_unref(dbconn);
return 0;
}
Please help me to fix.
Have a look here: http://www.freedesktop.org/wiki/IntroductionToDBus/
From what it looks like you need to write a file "*.service" that describes the service.
(Quoted from the website)
# (Lines starting with hash marks are comments)
# Fixed section header (do not change):
[D-BUS Service]
Names=com.bigmoneybank.Deposits;com.bigmoneybank.Withdrawals
Exec=/usr/local/bin/bankcounter
This is what I found within 5 minutes of Googleing.

zmq_socket() is giving segmentation fault

I am learning zeromq and have the following test code:
void *context = (void *)zmq_ctx_new();
if (context == NULL) {
printf("context is null\n");
} else {
printf("context was created successfully\n");
}
printf("connecting to the 0mq server\n");
void *responder = zmq_socket (context, ZMQ_REQ);
printf("got socket\n");
if (responder == NULL) {
printf("responder is null\n");
} else {
printf("responder was created successfully\n");
}
When I run the code, it crashes when the zmq_socket() is called. Here is the output:
Starting 0mq server context was created successfully connecting to the
0mq server Segmentation fault (core dumped)
I'm not sure why zmq_socket() fails. I have tried to move the zmq library in the beginning of the linking series in my Makefile. It still fails.
Any help would be highly appreciated.
change
void context = (void)zmq_ctx_new();
into
void *context = (void *)zmq_ctx_new();
And, as I tried your code, void context = (void) zmq_ctx_new() would cause compile error.
here is my code which can work on my OSX.
gcc -o cli client.c -lzmq
gcc -o srv server.c -lzmq
client.c:
#include <zmq.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
int main (void)
{
printf ("Connecting to hello world server…\n");
void *context = (void *)zmq_ctx_new ();
void *requester = zmq_socket (context, ZMQ_REQ);
zmq_connect (requester, "tcp://localhost:5555");
int request_nbr;
for (request_nbr = 0; request_nbr != 10; request_nbr++) {
char buffer [10];
char snd[] = "hello";
printf ("Sending Hello %d…\n", request_nbr);
zmq_send (requester, snd, sizeof(snd), 0);
zmq_recv (requester, buffer, 10, 0);
printf ("Received World %d\n", request_nbr);
}
zmq_close (requester);
zmq_ctx_destroy (context);
return 0;
}
server.c:
#include <zmq.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
int main (void)
{
// Socket to talk to clients
void *context = zmq_ctx_new ();
void *responder = zmq_socket (context, ZMQ_REP);
int rc = zmq_bind (responder, "tcp://*:5555");
assert (rc == 0);
while (1) {
int nrecv;
char buffer [10];
nrecv = zmq_recv (responder, buffer, 10, 0);
printf ("[%d] Received %s\n", nrecv, buffer);
sleep (1); // Do some 'work'
zmq_send (responder, "World", 5, 0);
}
return 0;
}

Get freeswitch events using ZMQ

I want to get events from freeswitch using ZMQ. I have enable mod_event_socket and mod_event_zmq in freeswitch and I am using following code to receive events but I am not getting anything.
#include <zmq.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
static char * s_recv (void *socket) {
char buffer [256];
int size = zmq_recv (socket, buffer, 255, 0);
if (size == -1)
return NULL;
if (size > 255)
size = 255;
buffer [size] = 0;
return strdup (buffer);
}
int main (int argc, char *argv [])
{
// Socket to talk to server
void *context = zmq_ctx_new ();
void *subscriber = zmq_socket (context, ZMQ_SUB);
int rc = zmq_connect (subscriber, "tcp://10.50.202.169:5556");
assert (rc == 0);
char filter[256] = {0};
rc = zmq_setsockopt (subscriber, ZMQ_SUBSCRIBE,
"", 256);
assert (rc == 0);
// Process 100 updates
int update_nbr;
for (update_nbr = 0; update_nbr < 100; update_nbr++) {
char *string = s_recv (subscriber);
printf("%s",string);
free (string);
}
zmq_close (subscriber);
zmq_ctx_destroy (context);
return 0;
}
I am using default configurations for both these modules of freeswitch.
was the zmq connection to FreeSWITCH successful?
did FreeSWITCH actually load mod_event_zmq module?

Resources