ZeroMQ 服务端与客户端通信案例[转]

ZeroMQ 服务端与客户端通信案例[转]

客户端:

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "zmq.hpp"
#include <Windows.h>

#pragma comment(lib,"unity.lib")
#pragma comment(lib,"testutil-static.lib")
#pragma comment(lib,"testutil.lib")
#pragma comment(lib,"libzmq-v140-mt-gd-4_3_5.lib")
#pragma comment(lib,"libzmq-v140-mt-sgd-4_3_5.lib")

int main(void)
{
	printf("Connecting to hello world server...\n");
	//创建上下文
	void *context = 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++) {
		//发送Hello
		char buffer[10];
		printf("Sending Hello %d...\n", request_nbr);
		zmq_send(requester, "Hello", 5, 0);

		//接收 World
		zmq_recv(requester, buffer, 10, 0);
		printf("Received World %d\n", request_nbr);
	}
	//关闭套接字
	zmq_close(requester);
	//释放上下文
	zmq_ctx_destroy(context);
	return 0;
}

服务端:

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "zmq.h"
#include <Windows.h>

#pragma comment(lib,"unity.lib")
#pragma comment(lib,"testutil-static.lib")
#pragma comment(lib,"testutil.lib")
#pragma comment(lib,"libzmq-v140-mt-gd-4_3_5.lib")
#pragma comment(lib,"libzmq-v140-mt-sgd-4_3_5.lib")

int main(void)
{
	//创建上下文
	void *context = zmq_ctx_new();
	//创建套接字
	void *responder = zmq_socket(context, ZMQ_REP);
	//绑定端口
	int rc = zmq_bind(responder, "tcp://*:5555");
	assert(rc == 0);

	while (1) {
		//接收信息
		char buffer[10];
		zmq_recv(responder, buffer, 10, 0);
		printf("Received Hello\n");
		Sleep(100);  //  Do some 'work'

		//发送World信息
		zmq_send(responder, "World", 5, 0);
	}
	return 0;
}
  • 输出:

 ZeroMQ 字符串规则

  • ZeroMQ字符串是指定长度的,并且在线路上发送时不含结尾空字符。
  • 最简单情况下,一个ZeroMQ字符串整齐的映射到一个ZeroMQ消息帧。
  • 示例(从套接字接收ZeroMQ字符串并转为C字符串),更多参考“zhelpers.h”
static char *s_recv(void* socket)
{
    zmq_msg_t message;
    zmq_msg_init(&message);
 
    int size = zmq_msg_recv(&message, socket, 0);
    if(size == -1)
        return NULL;
 
    char *string = (char*)malloc(size + 1);
    memcpy(string, zmq_msg_data(&message), size);
 
    zmq_msg_close(&message);
    string[size] = 0;
    return (string);
}
  • 发布-订阅案例
  • 服务端:
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "zmq.hpp"
#include <Windows.h>

#ifdef DEBUG_0MQ
#pragma comment(lib,"unity.lib")
#pragma comment(lib,"testutil-static.lib")
#pragma comment(lib,"testutil.lib")
#pragma comment(lib,"libzmq-v140-mt-gd-4_3_5.lib")
#pragma comment(lib,"libzmq-v140-mt-sgd-4_3_5.lib")
#else
#pragma comment(lib,"unity.lib")
#pragma comment(lib,"testutil-static.lib")
#pragma comment(lib,"testutil.lib")
#pragma comment(lib,"libzmq-v140-mt-4_3_5.lib")
#pragma comment(lib,"libzmq-v140-mt-s-4_3_5.lib")
#endif

#if (defined (WIN32))
#   define srandom srand
#   define random rand
#endif
// 生成随机数 从0到(num - 1)
#define randof(num)  (int) ((float) (num) * random () / (RAND_MAX + 1.0))

//发送数据
static int s_send(void *socket, char *string);

int main(void)
{
	//创建上下文
	void *context = zmq_ctx_new();
	//创建套接字,并设置为发布
	void *publisher = zmq_socket(context, ZMQ_PUB);
	//绑定IP端口
	int rc = zmq_bind(publisher, "tcp://*:5556");
	assert(rc == 0);
	rc = zmq_bind(publisher, "ipc://weather.ipc");
	assert(rc == 0);


	//生成随机值
	srandom((unsigned)time(NULL));
	while (1) {
		//生成信息
		int zipcode, temperature, relhumidity;
		zipcode = randof(100000);
		temperature = randof(215) - 80;
		relhumidity = randof(50) + 10;

		//发布消息给订阅者
		char update[20];
		sprintf(update, "%05d %d %d\n", zipcode, temperature, relhumidity);
		//Sleep(1000);
		//printf("%05d %d %d\n", zipcode, temperature, relhumidity);

		s_send(publisher, update);
	}
	//关闭、释放资源
	zmq_close(publisher);
	zmq_ctx_destroy(context);
	return 0;
}

static int s_send(void *socket, char *string)
{
	zmq_msg_t msg;
	zmq_msg_init_size(&msg, strlen(string));
	memcpy(zmq_msg_data(&msg), string, strlen(string));
	//发送数据
	int rc = zmq_msg_send(&msg, socket, 0);
	// 关闭zmq_msg_t对象
	zmq_msg_close(&msg);
	return rc;
}
  • 客户端:
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "zmq.h"
#include <Windows.h>

//#define DEBUG_0MQ

#ifdef DEBUG_0MQ
#pragma comment(lib,"unity.lib")
#pragma comment(lib,"testutil-static.lib")
#pragma comment(lib,"testutil.lib")
#pragma comment(lib,"libzmq-v140-mt-gd-4_3_5.lib")
#pragma comment(lib,"libzmq-v140-mt-sgd-4_3_5.lib")
#else
#pragma comment(lib,"unity.lib")
#pragma comment(lib,"testutil-static.lib")
#pragma comment(lib,"testutil.lib")
#pragma comment(lib,"libzmq-v140-mt-4_3_5.lib")
#pragma comment(lib,"libzmq-v140-mt-s-4_3_5.lib")
#endif


#if (defined (WIN32))
#   define srandom srand
#   define random rand
#endif
// 生成随机数 从0到(num - 1)
#define randof(num)  (int) ((float) (num) * random () / (RAND_MAX + 1.0))

//接收消息
static char *s_recv(void* socket);

int main(int argc, char *argv[])
{
	printf("Collecting updates from weather server...\n");
	//创建上下文
	void *context = zmq_ctx_new();
	//创建套接字,设置Wie订阅
	void *subscriber = zmq_socket(context, ZMQ_SUB);
	//连接服务器
	int rc = zmq_connect(subscriber, "tcp://localhost:5556");
	assert(rc == 0);

	//订阅邮政编码,默认NYC 10001
	const char *filter = (argc > 1) ? argv[1] : "10001 ";
	rc = zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, filter, strlen(filter));
	assert(rc == 0);

	//更新100条
	int update_nbr;
	long total_temp = 0;
	for (update_nbr = 0; update_nbr < 10; update_nbr++)
	{
		printf("开始接收第 %d 信息\n", update_nbr);
		char *string = s_recv(subscriber);
		printf("%s\n", string);
		int zipcode, temperature, relhumidity;
		sscanf(string, "%d %d %d", &zipcode, &temperature, &relhumidity);
		total_temp += temperature;
		free(string);
	}

	printf("Average temperature for zipcode '%s' was %dF\n",
		filter, (int)(total_temp / update_nbr));

	//关闭、释放资源
	zmq_close(subscriber);
	zmq_ctx_destroy(context);
	return 0;
}

//接收消息
static char *s_recv(void* socket)
{
	zmq_msg_t message;
	zmq_msg_init(&message);

	int size = zmq_msg_recv(&message, socket, 0);
	if (size == -1)  return NULL;

	char *string = (char*)malloc(size + 1);
	memcpy(string, zmq_msg_data(&message), size);

	zmq_msg_close(&message);
	string[size] = 0;
	return string;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值