ZMQ(PUB-SUB)
服务端不管客户端这边有没有接收到数据,只负责发送。客户端不能发送数据,只负责接收。
(1)一个发布者,多个订阅者的关系,1:n;
(2)只有设置了与服务端发送消息相同订阅类型的客户端才能接收到消息
(3)服务端可以绑定多个端口
注:使用SUB设置一个订阅时,使用zmq_setsockopt()对消息进行过滤
C++示例代码:
服务端:
//server
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<zmq.h>
#include<assert.h>
using namespace std;
int main()
{
void *context = zmq_ctx_new();
void *socket = zmq_socket(context,ZMQ_PUB);
int ret = zmq_bind(socket, "tcp://*:6666");
assert(ret == 0);
ret = zmq_bind(socket, "tcp://*:5555"); //绑定另一个端口5555
assert(ret == 0);
int i = 0; //消息计数器
while (1)
{
Sleep(10);
char sendBuf[1024] = {0};
sprintf(sendBuf, "[Server] : server = %d", i++);
int sentBytes = zmq_send(socket, sendBuf, strlen(sendBuf), 0);
if (sentBytes > 0)
{
printf("%s\n", sendBuf);
}
}
zmq_close(socket);
zmq_ctx_destroy(context);
system("pause");
return 0;
}
客户端1:(接收6666端口消息)
//客户端1:接收服务端 6666端口的消息
#include<iostream>
#include<thread>
#include<zmq.h>
#include<assert.h>
using namespace std;
void Recv1(void *arg); //客户端接收线程1
void Recv2(void *arg); //客户端接收线程2
int main()
{
void *context = zmq_ctx_new();
assert(context != NULL);
void *socket = zmq_socket(context,ZMQ_SUB);
assert(socket != NULL);
int ret = zmq_connect(socket, "tcp://localhost:6666");
assert(ret == 0);
ret = zmq_setsockopt(socket, ZMQ_SUBSCRIBE, "[Server]", 8);
assert(ret == 0);
thread th1(Recv1,socket);
thread th2(Recv2,socket);
th1.join();
th2.join();
zmq_close(socket);
zmq_ctx_destroy(context);
system("pause");
return 0;
}
void Recv1(void *arg) //客户端接收线程1
{
void *socket = arg;
while(1)
{
char recvBuf[1024] = { 0 };
Sleep(1);
int recvBytes = zmq_recv(socket, recvBuf, sizeof(recvBuf)-1, 0);
if (recvBytes > 0)
{
printf("[Client] : Recv1--------------:%s\n", recvBuf);
}
}
}
void Recv2(void *arg) //客户端接收线程2
{
void *socket = arg;
while (1)
{
char recvBuf[1024] = { 0 };
Sleep(1);
int recvBytes = zmq_recv(socket, recvBuf, sizeof(recvBuf)-1, 0);
if (recvBytes > 0)
{
printf("[Client] : Recv2--------------:%s\n", recvBuf);
}
}
}
客户端2:接收5555端口消息
//客户端2:接收5555端口
#include<iostream>
#include<thread>
#include<zmq.h>
#include<assert.h>
using namespace std;
void Recv3(void *arg); //客户端接收线程3
int main()
{
void *context = zmq_ctx_new();
void *socket = zmq_socket(context, ZMQ_SUB);
int ret = zmq_connect(socket, "tcp://localhost:5555");
assert(ret == 0);
thread th3(Recv3, socket);
th3.join();
zmq_close(socket);
zmq_ctx_destroy(context);
system("pause");
return 0;
}
void Recv3(void *arg) //客户端接收线程3
{
void *socket = arg;
int ret = zmq_setsockopt(socket, ZMQ_SUBSCRIBE, "", 0);
assert(ret == 0);
while (1)
{
char recvBuf[1024] = { 0 };
Sleep(1);
int recvBytes = zmq_recv(socket, recvBuf, sizeof(recvBuf)-1, 0);
if (recvBytes > 0)
{
printf("[Client] : Recv3--------------:%s\n", recvBuf);
}
}
}
测试结果:
先运行两个客户端,再运行服务端,两个客户端如果设置的过滤一致,那它们接收到的消息应该相同;