既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
| — |
| ZMQ_PUB特性摘要 |
| 兼容的对等套接字 | ZMQ_SUB、ZMQ_XSUB |
| 方向 | 单向 |
| 发送/接收模式 | 仅发送 |
| 入网路由策略 | 不适用(N/A) |
| 外发路由策略 | 扇出(Fan out) |
| 静音状态下的操作 | 丢弃 |ZMQ_SUB
- 订阅者使用ZMQ_SUB类型的套接字来订阅发布者分发的数据
- ZMQ_SUB套接字创建完成之后,ZMQ_SUB套接字未订阅任何消息,请使用zmq_setsockopt()的ZMQ_SUBSCRIBE选项指定要订阅的消息
- 在ZMQ_PUB类型的套接字上不能执行zmq_msg_recv()等接收数据的函数
ZMQ_SUB特性摘要 兼容的对等套接字 方向 发送/接收模式 入网路由策略 外发路由策略
- 下面编写一个使用“SUB-PUB”的发布订阅演示案例:
- **发布者:**类似于一个天气更新服务器,向订阅者发送天气更新,内容包括邮政编码、温度、湿度等信息
- **订阅者:**它监听发布者更新的数据流,过滤只接收与特定邮政编码相关的天气信息,默认接收接收10条数据
- 发布者代码如下:
// 源码链接:https://github.com/dongyusheng/csdn-code/blob/master/ZeroMQ/wuserver.c
// wuserver.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <zmq.h>
// 随机生成0...num-1的随机数
#define randof(num) (int) ((float) (num) * random () / (RAND_MAX + 1.0))
// 将string消息格式化为zmq_meg_t对象, 然后发往socket套接字上
static int s_send(void *socket, char *string);
int main()
{
// 1.初始化上下文
void *context = zmq_ctx_new();
// 2.创建、绑定套接字
void *publisher = zmq_socket(context, ZMQ_PUB);
assert(publisher != NULL);
// 此处我们将发布者绑定到一个tcp节点上和一个ipc节点上, 但是本案例我们只使用tcp, ipc那个只是演示说明zmq的套接字可以绑定到多个节点上
int rc = zmq_bind(publisher, "tcp://*:5555");
assert(rc == 0);
rc = zmq_bind(publisher, "ipc://weather.ipc");
assert(rc == 0);
// 3.初始化随机数发生器
srandom((unsigned)time(NULL));
// 4.循环发送数据
while(1)
{
// 5.随机生成邮政编码、温度、适度
int zipcode, temperature, relhumidity;
zipcode = randof(100000);
temperature = randof(215) - 80;
relhumidity = randof(50) + 10;
// 6.将消息发送给所有的订阅者
char update[20];
sprintf(update, "%05d %d %d", zipcode, temperature, relhumidity);
rc = s_send(publisher, update);
assert(rc);
}
// 7.关闭套接字、销毁上下文
zmq_close(publisher);
zmq_ctx_destroy(context);
return 0;
}
static int s_send(void *socket, char *string)
{
// 初始化一个zmq_msg_t对象, 分配的大小为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;
}
- 订阅者代码如下:
// 源码链接:https://github.com/dongyusheng/csdn-code/blob/master/ZeroMQ/wuclient.c
// wuclient.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <zmq.h>
// 从socket接收数据, 并将数据返回
char *s_recv(void *socket);
int main(int argc, char *argv[])
{
// 1.初始化上下文
void *context = zmq_ctx_new();
// 2.创建套接字、连接发布者
void *subscriber = zmq_socket(context, ZMQ_SUB);
assert(subscriber != NULL);
int rc = zmq_connect(subscriber, "tcp://localhost:5555");
assert(rc == 0);
// 3.因为自己是订阅者, 因此需要使用设置过滤器, 显式指定自己是否需要接收什么类型的消息
// 程序运行时可以输入参数, 参数代表邮政编码, 如果参数为空, 那么就过滤10001的消息
char *filter = (argc > 1) ? argv[1] : "10001";
rc = zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, filter, strlen(filter));
assert( rc == 0);
// 4.从发布者那里接收消息, 接收10条自己想要的数据
int update_nbr;
long total_temp = 0;
for(update_nbr = 0; update_nbr < 10; update_nbr++)
{
// 5.接收数据
char *string = s_recv(subscriber);
assert(string != NULL);
// 6.将数据中的邮政编码、温度、适度分别存储变量中
int zipcode, temperature, relhumidity;
sscanf(string, "%d %d %d", &zipcode, &temperature, &relhumidity);
total_temp += temperature;
free(string);
}
// 7.接收完成之后, 打印一下平均温度
printf("Average tempature for zipcode '%s' was %dF\n", filter, (int)(total_temp / update_nbr));
// 8.关闭套接字、销毁上下文
zmq_close(subscriber);
zmq_ctx_destroy(context);
return 0;
}
char *s_recv(void *socket)
{
// 创建zmq_msg_t对象接收数据
zmq_msg_t msg;
zmq_msg_init(&msg);
int size = zmq_msg_recv(&msg, socket, 0);
if(size == -1)
{
return NULL;
}
// 将zmq_msg_t对象中的数据保存到字符串中
char *string = (char*)malloc(size + 1);
memcpy(string, zmq_msg_data(&msg), size);
zmq_msg_close(&msg);
string[size] = 0;
return string;
}
- 编译如下:
gcc -o wuserver wuserver.c -lzmq
gcc -o wuclient wuclient.c -lzmq
- **一次运行如下,**左侧为发布者,右侧为订阅者,订阅者没有传入参数,因此默认订阅的是邮政编码为“10001”的数据
- **又运行一次如下,**订阅者传入的参数为“10002”,因此订阅的是邮政编码为“10002”的数据
四、“XPUB-XSUB”套接字类型
- “XPUB-XSUB”套接字类型与“PUB-SUB”套接字类型相同,也是属于发布-订阅
- 在“PUB-SUB”中,订阅者通过zmq_connect()向发布者发起订阅;但是“XPUB-XSUB”套接字类型允许订阅者通过发送一条订阅信息到发布者来完成订阅
ZMQ_XPUB
- 用法与ZMQ_PUB大部分相同
- **但是有一点与ZMQ_PUB不同:**ZMQ_XPUB(自己)的订阅方可以向自己发送一个订阅信息来进行订阅。订阅消息是字节1(用于订阅)或字节0(用于取消订阅),后跟订阅主体。也接收不带子/取消订阅前缀的消息,但对订阅状态没有影响
| |
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
rC7-1715891091333)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!