#include <zmq.hpp> #include <string> #include <iostream> #include <windows.h> #include<zhelpers.hpp> using namespace std;DWORD WINAPI MyThread_client(LPVOID lpParamter)
{
zmq::context_t context (1);
//建立套接字
zmq::socket_t socket (context, ZMQ_REQ);std::cout </span><< <span style="color: #800000;">"</span><span style="color: #800000;">Connecting to hello world server...</span><span style="color: #800000;">"</span> <<<span style="color: #000000;"> std::endl; </span><span style="color: #008000;">//</span><span style="color: #008000;">连接服务器</span> socket.connect (<span style="color: #800000;">"</span><span style="color: #800000;">tcp://localhost:5555</span><span style="color: #800000;">"</span><span style="color: #000000;">); </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> request_nbr = <span style="color: #800080;">0</span>; request_nbr != <span style="color: #800080;">10</span>; request_nbr++<span style="color: #000000;">) { s_send (socket, </span><span style="color: #800000;">"</span><span style="color: #800000;">hello</span><span style="color: #800000;">"</span><span style="color: #000000;">); std::cout </span><< <span style="color: #800000;">"</span><span style="color: #800000;">Client1 Received :</span><span style="color: #800000;">"</span> <<s_recv (socket)<<<span style="color: #000000;"> std::endl; Sleep(</span><span style="color: #800080;">1000</span><span style="color: #000000;">); } </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">0</span><span style="color: #000000;">;
}
DWORD WINAPI MyThread_client1(LPVOID lpParamter)
{
zmq::context_t context (1);
//建立套接字
zmq::socket_t socket (context, ZMQ_REQ);std::cout </span><< <span style="color: #800000;">"</span><span style="color: #800000;">Connecting to hello world server...</span><span style="color: #800000;">"</span> <<<span style="color: #000000;"> std::endl; </span><span style="color: #008000;">//</span><span style="color: #008000;">连接服务器</span> socket.connect (<span style="color: #800000;">"</span><span style="color: #800000;">tcp://localhost:5555</span><span style="color: #800000;">"</span><span style="color: #000000;">); </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> request_nbr = <span style="color: #800080;">0</span>; request_nbr != <span style="color: #800080;">10</span>; request_nbr++<span style="color: #000000;">) { s_send (socket, </span><span style="color: #800000;">"</span><span style="color: #800000;">SB</span><span style="color: #800000;">"</span><span style="color: #000000;">); std::cout </span><< <span style="color: #800000;">"</span><span style="color: #800000;">Client2 Received :</span><span style="color: #800000;">"</span> <<s_recv (socket)<<<span style="color: #000000;"> std::endl; Sleep(</span><span style="color: #800080;">1000</span><span style="color: #000000;">); } </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">0</span><span style="color: #000000;">;
}
DWORD WINAPI MyThread_servce(LPVOID lpParamter)
{
zmq::context_t context (1);
zmq::socket_t socket (context, ZMQ_REP);
//绑定端口
socket.bind ("tcp://*:5555");</span><span style="color: #0000ff;">while</span> (<span style="color: #0000ff;">true</span><span style="color: #000000;">) { std::cout </span><< <span style="color: #800000;">"</span><span style="color: #800000;">Servce Received: </span><span style="color: #800000;">"</span><<s_recv (socket)<<<span style="color: #000000;"> std::endl; s_send (socket, </span><span style="color: #800000;">"</span><span style="color: #800000;">world</span><span style="color: #800000;">"</span><span style="color: #000000;">); }
}
int main ()
{HANDLE hThread1 </span>= CreateThread(NULL, <span style="color: #800080;">0</span>, MyThread_client, NULL, <span style="color: #800080;">0</span><span style="color: #000000;">, NULL); HANDLE hThread2 </span>= CreateThread(NULL, <span style="color: #800080;">0</span>, MyThread_servce, NULL, <span style="color: #800080;">0</span><span style="color: #000000;">, NULL); HANDLE hThread3 </span>= CreateThread(NULL, <span style="color: #800080;">0</span>, MyThread_client1, NULL, <span style="color: #800080;">0</span><span style="color: #000000;">, NULL); </span><span style="color: #0000ff;">while</span>(<span style="color: #800080;">1</span><span style="color: #000000;">); </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">0</span><span style="color: #000000;">;
}
运行结果:
这里我建立了两个客户端和一个服务器,每个都独立运行一个线程。客户端1发了“hello”,客户端2发了“SB”,服务器都能接收到并且返回了world。
2:发布订阅模式(PUB-SUB)
所谓发布订阅,比如天气预报,当很多人订阅之后,中心服务器直接往订阅的人发送就可以了,不需要管对方有没有收到。也就是1对N的模式。这里还有重要的一个概念,频道:跟收音机的频道类似,订阅者设定了频道才能听到该频道的消息
看例程序:
#include <zmq.hpp> #include <string> #include <iostream> #include <windows.h> #include<zhelpers.hpp> using namespace std;//订阅1
DWORD WINAPI MyThread_sub1(LPVOID lpParamter)
{
zmq::context_t context(1);
zmq::socket_t subscriber (context, ZMQ_SUB);
//连接
subscriber.connect("tcp://localhost:5563");
//设置频道B
subscriber.setsockopt( ZMQ_SUBSCRIBE, "A", 1);
while (1) {</span><span style="color: #008000;">//</span><span style="color: #008000;"> Read envelope with address</span> std::<span style="color: #0000ff;">string</span> address =<span style="color: #000000;"> s_recv (subscriber); </span><span style="color: #008000;">//</span><span style="color: #008000;"> Read message contents</span> std::<span style="color: #0000ff;">string</span> contents =<span style="color: #000000;"> s_recv (subscriber); std::cout </span><< <span style="color: #800000;">"</span><span style="color: #800000;">订阅1:[</span><span style="color: #800000;">"</span> << address << <span style="color: #800000;">"</span><span style="color: #800000;">] </span><span style="color: #800000;">"</span> << contents <<<span style="color: #000000;"> std::endl; } </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">0</span><span style="color: #000000;">;
}
//订阅2
DWORD WINAPI MyThread_sub2(LPVOID lpParamter)
{
zmq::context_t context(1);
zmq::socket_t subscriber (context, ZMQ_SUB);
//连接
subscriber.connect("tcp://localhost:5563");
//设置频道B
subscriber.setsockopt( ZMQ_SUBSCRIBE, "B", 1);
while (1) {</span><span style="color: #008000;">//</span><span style="color: #008000;"> Read envelope with address</span> std::<span style="color: #0000ff;">string</span> address =<span style="color: #000000;"> s_recv (subscriber); </span><span style="color: #008000;">//</span><span style="color: #008000;"> Read message contents</span> std::<span style="color: #0000ff;">string</span> contents =<span style="color: #000000;"> s_recv (subscriber); std::cout </span><< <span style="color: #800000;">"</span><span style="color: #800000;">订阅2:[</span><span style="color: #800000;">"</span> << address << <span style="color: #800000;">"</span><span style="color: #800000;">] </span><span style="color: #800000;">"</span> << contents <<<span style="color: #000000;"> std::endl; } </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">0</span><span style="color: #000000;">;
}
//订阅3
DWORD WINAPI MyThread_sub3(LPVOID lpParamter)
{
zmq::context_t context(1);
zmq::socket_t subscriber (context, ZMQ_SUB);
//连接
subscriber.connect("tcp://localhost:5563");
//设置频道B
// subscriber.setsockopt( ZMQ_SUBSCRIBE, "B", 1);
while (1) {</span><span style="color: #008000;">//</span><span style="color: #008000;"> Read envelope with address</span> std::<span style="color: #0000ff;">string</span> address =<span style="color: #000000;"> s_recv (subscriber); </span><span style="color: #008000;">//</span><span style="color: #008000;"> Read message contents</span> std::<span style="color: #0000ff;">string</span> contents =<span style="color: #000000;"> s_recv (subscriber); std::cout </span><< <span style="color: #800000;">"</span><span style="color: #800000;">订阅3:[</span><span style="color: #800000;">"</span> << address << <span style="color: #800000;">"</span><span style="color: #800000;">] </span><span style="color: #800000;">"</span> << contents <<<span style="color: #000000;"> std::endl; } </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">0</span><span style="color: #000000;">;
}
//发布线程
DWORD WINAPI MyThread_pub(LPVOID lpParamter)
{
// Prepare our context and publisher
zmq::context_t context(1);
zmq::socket_t publisher(context, ZMQ_PUB);
publisher.bind("tcp://*:5563");</span><span style="color: #0000ff;">while</span> (<span style="color: #800080;">1</span><span style="color: #000000;">) { </span><span style="color: #008000;">//</span><span style="color: #008000;"> Write two messages, each with an envelope and content</span> s_sendmore (publisher, <span style="color: #800000;">"</span><span style="color: #800000;">A</span><span style="color: #800000;">"</span><span style="color: #000000;">); s_send (publisher, </span><span style="color: #800000;">"</span><span style="color: #800000;">We don't want to see this</span><span style="color: #800000;">"</span><span style="color: #000000;">); Sleep (</span><span style="color: #800080;">100</span><span style="color: #000000;">); s_sendmore (publisher, </span><span style="color: #800000;">"</span><span style="color: #800000;">B</span><span style="color: #800000;">"</span><span style="color: #000000;">); s_send (publisher, </span><span style="color: #800000;">"</span><span style="color: #800000;">We would like to see this</span><span style="color: #800000;">"</span><span style="color: #000000;">); Sleep (</span><span style="color: #800080;">100</span><span style="color: #000000;">); }
}
int main ()
{
HANDLE hThread1 = CreateThread(NULL, 0, MyThread_pub, NULL, 0, NULL);
Sleep(1000);
HANDLE hThread2 = CreateThread(NULL, 0, MyThread_sub1, NULL, 0, NULL);
HANDLE hThread3 = CreateThread(NULL, 0, MyThread_sub2, NULL, 0, NULL);
HANDLE hThread4 = CreateThread(NULL, 0, MyThread_sub3, NULL, 0, NULL);
while(1);
return 0;
}
结果: