ZMQ专题学习之五:libzmq的管道通信方式
接上一节,简单的展示了调用libzmq实现publisher-subscribe模式的实例,这一节开始介绍管道模式的实例。
今天展示的是管道模式:
第一步:先建立工程文件,与上一节一样,建立一个testLibzmqVentilator工程,以控制台的项目方式建立。
第二步:参照上节论述,在建立好的工程文件夹中建立两个目录,include和lib两个文件夹。
然后分别把 zmq.h 和zmq_utils.h拷贝到includes文件夹,libzmq.lib和libzmq.dll拷贝到lib文件夹中。(具体从哪里考,这里就不啰嗦了,对于熟悉vs环境的人,一点就透)。
第三步:设置附加包含目录、附加链接库,调试过dll的人都懂的,不再赘述。
第四步:在建立的工程文件的cpp的文件中,添加如下代码;
// testLibzmqVentilator.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <stdio.h>
#include "../include/zmq.h"
#define randof(num) (int) ((float) (int num) * rand() / (RAND_MAX + 1.0));
static int s_send (void *socket, char *string) {
int size = zmq_send (socket, string, strlen (string), 0);
return size;
}
int main (void)
{
// [0]创建对象
void *context = zmq_ctx_new ();
// [1]发送消息的嵌套字
void *sender = zmq_socket (context, ZMQ_PUSH);
zmq_bind(sender,"tcp://*:5557");
// [2]分发消息的嵌套字
void *sink = zmq_socket (context, ZMQ_PUSH);
zmq_connect(sink, "tcp://localhost:5558");
printf ("Press Enter when the workers are ready: ");
getchar ();
printf ("Sending tasks to workers...\n");
// [3]发送开始信号
s_send (sink, "0");
// [4]初始化随机数
srand(time(NULL));
// [5]发送100个任务
int task_nbr;
int total_msec = 0; // 预计执行时间(毫秒)
for (task_nbr = 0; task_nbr < 100; task_nbr++) {
int workload;
// 随机产生1-100毫秒
workload = (100) * rand() / (RAND_MAX + 1.0) + 1;
total_msec += workload;
char string [10];
sprintf (string, "%d", workload);
printf("send %s\n",string);
s_send (sender, string);
}
printf ("Total expected cost: %d msec\n", total_msec);
getchar();
zmq_close (sink);
zmq_close (sender);
zmq_ctx_destroy (context);
return 0;
}
第五步:编译后,会生成对应版本的,比如是release版本还是debug版本,32位,还是64位版本的exe。(本文为64位)
第六步:建立work的工程文件一个testLibzmqWork工程,以控制台的项目方式建立。
第七步:同样的操作,在建立好的工程文件夹中建立两个目录,include和lib两个文件夹。
然后分别把 zmq.h 和zmq_utils.h拷贝到includes文件夹,libzmq.lib和libzmq.dll拷贝到lib文件夹中。(具体从哪里考,这里就不啰嗦了,对于熟悉vs环境的人,一点就透)。
第八步:设置附加包含目录、附加链接库,调试过dll的人都懂的,不再赘述。
第九步:在建立的工程文件的cpp的文件中,添加如下代码;
// testLibzmqWork.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include "../include/zmq.h"
int s_send (void *socket, char *string) {
int size = zmq_send (socket, string, strlen (string), 0);
return size;
}
char *s_recv (void *socket) {
char buffer [256];
int size = zmq_recv (socket, buffer, 255, 0);
if (size == -1)
return NULL;
buffer[size] = '\0';
return buffer;
}
int main (void)
{
// [0]创建对象
void *context = zmq_ctx_new ();
// [1]发送消息的嵌套字
void *receiver = zmq_socket (context, ZMQ_PULL);
zmq_connect (receiver, "tcp://localhost:5557");
// [2]分发消息的嵌套字
void *sender = zmq_socket (context, ZMQ_PUSH);
zmq_connect (sender, "tcp://localhost:5558");
// [3]循环处理任务
while (1) {
char *string = s_recv (receiver);
printf ("work recieve:%s\n", string); // Show progress
fflush (stdout);
Sleep (atoi (string)*100); // Do the work
free (string);
s_send (sender, string); // Send results to sink
}
zmq_close (receiver);
zmq_close (sender);
zmq_ctx_destroy (context);
return 0;
}
第十步:编译后,会生成对应版本的,比如是release版本还是debug版本,32位,还是64位版本的exe。(本文为64位)
第十一步:建立Sink的工程文件一个testLibzmqSink工程,以控制台的项目方式建立。
第十二步:同样的操作,在建立好的工程文件夹中建立两个目录,include和lib两个文件夹。
然后分别把 zmq.h 和zmq_utils.h拷贝到includes文件夹,libzmq.lib和libzmq.dll拷贝到lib文件夹中。(具体从哪里考,这里就不啰嗦了,对于熟悉vs环境的人,一点就透)。
第十三步:设置附加包含目录、附加链接库,调试过dll的人都懂的,不再赘述。
第十四步:在建立的工程文件的cpp的文件中,添加如下代码;
// testLibzmqSink.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include "../include/zmq.h"
int s_send (void *socket, char *string) {
int size = zmq_send (socket, string, strlen (string), 0);
return size;
}
char *s_recv (void *socket) {
char buffer [256];
int size = zmq_recv (socket, buffer, 255, 0);
if (size == -1)
return NULL;
buffer[size] = '\0';
return buffer;
}
int main (void)
{
// [0]准备上下文和套接字
void *context = zmq_ctx_new ();
void *receiver = zmq_socket (context, ZMQ_PULL);
zmq_bind (receiver, "tcp://*:5558");
printf("Start Sink!\n");
// [1]等待开始信号
char string[20];
strcpy(string,s_recv (receiver));
printf("recive %s\n",string);
// [2]开始计时
time_t t;
t=time(NULL);
printf("start time %s\n",ctime(&t));
// [3]确定任务处理
int task_nbr;
for (task_nbr = 0; task_nbr < 100; task_nbr++) {
strcpy(string,s_recv (receiver));
printf("sink recieve: %s\n",string);
}
// Calculate and report duration of batch
printf ("Total elapsed time: msec\n");
t=time(NULL);
printf("%s\n",ctime(&t));
zmq_close (receiver);
zmq_ctx_destroy (context);
return 0;
}
第十五步:编译后,会生成对应版本的,比如是release版本还是debug版本,32位,还是64位版本的exe。(本文为64位)
至此,已经把三个样例工程文件编译完毕,分别在各自的release或者debug目录执行exe文件,执行界面如下:
ventilator的显示界面
work的显示界面
sink的显示界面
上面三个图显示了管道模式三个程序的相互通信的过程。
demo下载的地址:https://download.youkuaiyun.com/download/jyl_sh/12406913