/*************************************************************************
* > File Name: ZMQ_PipeSocket.h
* > Author: wangzhicheng
* > Mail: 2363702560@qq.com
* > Created Time: 2017-02-24
* > statement: ZMQ封装类
*************************************************************************/
#ifndef ZMQ_PIPE_SOCKET_H
#define ZMQ_PIPE_SOCKET_H
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <stdint.h>
#include <zmq.h>
#include <string>
namespace zmqpipe
{
using namespace std;
class ZMQ_PIPESocket
{
private:
void *m_pContext;
void *m_pSocket;
int m_nSocketType;
string m_strSendServer; // 发送的服务器地址
public:
ZMQ_PIPESocket();
~ZMQ_PIPESocket();
/*
* @brief 初始化zmq
* */
bool Init(int SocketType, const string &addr, bool Bind = true, int sendhwm = 1000, int recvhwm = 1000, int sendtimeout = 1000);
/*
* @brief 发送info指向的对象
* @len 对象的大小 字节数
* @return 发送成功返回true
* */
bool Send(void *info, int len);
/*
* @brief 发送string对象
* @return 发送成功返回true
* */
bool Send(const string &strSend);
/*
* @brief 接收数据 接收的数据由info指向
* @return 接收成功返回true
* */
bool Recv(void *info);
/*
* @brief 接收string对象数据
* @return 接收成功返回true
* */
bool Recv(string &strRecv);
/*
* @brief 获取发送服务器地址
* */
inline void GetSendAddr(string &strOut)
{
strOut = m_strSendServer;
}
/*
* @brief recieving from a socket is over
* */
bool RecvOver();
inline void *GetSocket() const
{
return m_pSocket;
}
};
}
#endif
/*************************************************************************
* > File Name: ZMQ_PipeSocket.cpp
* > Author: wangzhicheng
* > Mail: 2363702560@qq.com
* > Created Time: 2017-02-24
* > statement: ZMQ封装类
*************************************************************************/
#include "ZMQ_PipeSocket.h"
namespace zmqpipe
{
ZMQ_PIPESocket::ZMQ_PIPESocket()
{
m_pContext = NULL;
m_pSocket = NULL;
}
bool ZMQ_PIPESocket::Init(int SocketType, const string &addr, bool Bind, int sendhwm, int recvhwm, int sendtimeout)
{
m_pContext = zmq_ctx_new();
// m_pContext = zmq_init(1);
if(!m_pContext) return false;
m_pSocket = zmq_socket(m_pContext, SocketType);
if(!m_pSocket) return false;
int rc;
switch(SocketType)
{
case ZMQ_REP:
case ZMQ_PULL:
case ZMQ_PUB:
case ZMQ_ROUTER:
case ZMQ_DEALER:
rc = zmq_bind(this->m_pSocket, addr.c_str());
break;
case ZMQ_REQ:
case ZMQ_PUSH:
case ZMQ_SUB:
rc = zmq_connect(this->m_pSocket, addr.c_str());
break;
default:
if(ZMQ_PAIR == SocketType)
{
if(Bind)
{
rc = zmq_bind(this->m_pSocket, addr.c_str());
}
else
{
rc = zmq_connect(this->m_pSocket, addr.c_str());
}
}
else return false;
}
if(rc) return false;
rc = zmq_setsockopt(m_pSocket, ZMQ_SNDHWM, &sendhwm, sizeof(sendhwm));
if(rc) return false;
rc = zmq_setsockopt(m_pSocket, ZMQ_RCVHWM, &recvhwm, sizeof(recvhwm));
if(rc) return false;
rc = zmq_setsockopt(m_pSocket, ZMQ_SNDTIMEO, &sendtimeout, sizeof(sendtimeout));
if(rc) return false;
if(ZMQ_SUB == SocketType) zmq_setsockopt(m_pSocket, ZMQ_SUBSCRIBE, "", 0);
m_strSendServer = addr;
return true;
}
/*
* @brief 发送info指向的对象
* @len 对象的大小 字节数
* */
bool ZMQ_PIPESocket::Send(void *info, int len)
{
int rc;
zmq_msg_t msg;
rc = zmq_msg_init_size(&msg, len);
if(rc) return false;
memcpy(zmq_msg_data(&msg), (char *)info, len);
rc = zmq_msg_send(&msg, this->m_pSocket, 0);
return rc == len;
}
/*
* @brief 发送string对象
* */
bool ZMQ_PIPESocket::Send(const string &strSend)
{
int rc;
size_t len = strSend.size();
zmq_msg_t msg;
rc = zmq_msg_init_size(&msg, len);
if(rc) return false;
memcpy(zmq_msg_data(&msg), strSend.c_str(), len);
size_t Len = zmq_msg_send(&msg, this->m_pSocket, 0);
return Len == len;
}
/*
* @brief 接收数据 接收的数据由info指向
* */
bool ZMQ_PIPESocket::Recv(void *info)
{
int rc;
zmq_msg_t msg;
rc = zmq_msg_init(&msg);
if(rc) return false;
int len = zmq_msg_recv(&msg, this->m_pSocket, 0); // 阻塞方式
if(len <= 0) return false;
memcpy(info, (char *)zmq_msg_data(&msg), len);
if(zmq_msg_close(&msg)) return false;
return true;
}
/*
* @brief 接收string对象数据
* */
bool ZMQ_PIPESocket::Recv(string &strRecv)
{
int rc;
zmq_msg_t msg;
rc = zmq_msg_init(&msg);
if(rc) return false;
int len = zmq_msg_recv(&msg, this->m_pSocket, 0); // 阻塞方式
if(len <= 0) return false;
strRecv.assign((char *)zmq_msg_data(&msg), len);
if(zmq_msg_close(&msg)) return false;
return true;
}
/*
* @brief recieving from a socket is over
* */
bool ZMQ_PIPESocket::RecvOver()
{
int64_t more;
size_t more_size = sizeof(more);
zmq_getsockopt(m_pSocket, ZMQ_RCVMORE, &more, &more_size);
return more <= 0;
}
ZMQ_PIPESocket::~ZMQ_PIPESocket()
{
if(m_pSocket)
{
zmq_close(m_pSocket);
m_pSocket = NULL;
}
if(m_pContext)
{
zmq_ctx_destroy(m_pContext);
m_pContext = NULL;
}
}
}
/*************************************************************************
> File Name: test.cpp
> Author: wangzhicheng
> Mail: 2363702560@qq.com
> Created Time:2017-02-25
************************************************************************/
#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include "ZMQ_PipeSocket.h"
using namespace zmqpipe;
static const string ADDR_PUB = "tcp://*:8888";
static const string ADDR_PUB_SYN = "tcp://*:9999";
static const string ADDR_SUB = "tcp://127.0.0.1:8888";
static const string ADDR_SUB_SYN = "tcp://127.0.0.1:9999";
void Publisher()
{
string str;
ZMQ_PIPESocket publisher;
if(!publisher.Init(ZMQ_PUB, ADDR_PUB))
{
cerr << "publisher init failed...!" << endl;
return;
}
ZMQ_PIPESocket syn;
if(!syn.Init(ZMQ_REP, ADDR_PUB_SYN))
{
cerr << "pub syn init failed...!" << endl;
return;
}
// synchronize
syn.Recv(str);
cout << "publisher syn recv = " << str << endl;
if(!syn.Send(str))
{
cerr << str << "pub syn failed...!" << endl;
}
else
{
cout << "publisher syn send successfully...!" << endl;
}
cout << "publisher syn over...!" << endl;
// pub begin
str = "I am a pub...!";
if(!publisher.Send(str))
{
cerr << str << "send failed...!" << endl;
return;
}
else
{
cout << "publisher pub successfully...!" << endl;
}
str = "END";
if(!publisher.Send(str))
{
cerr << str << "send failed...!" << endl;
}
else
{
cout << str << " send successfully...!" << endl;
}
}
void Subscriber()
{
string str = "I am a subscriber...!";
ZMQ_PIPESocket subscriber;
if(!subscriber.Init(ZMQ_SUB, ADDR_SUB))
{
cerr << "subscriber init failed...!" << endl;
return;
}
ZMQ_PIPESocket syn;
if(!syn.Init(ZMQ_REQ, ADDR_SUB_SYN))
{
cerr << "sub syn init failed...!" << endl;
return;
}
sleep(1);
// synchronize
cout << "subcriber syn begin...!" << endl;
if(!syn.Send(str))
{
cerr << "subscriber syn failed...!" << endl;
return;
}
else
{
cout << "subscriber syn send successfully...!" << endl;
}
cout << "wait publisher response" << endl;
syn.Recv(str);
cout << "subcriber syn recv = " << str << endl;
cout << "subcriber syn over...!" << endl;
// sub begin
while(1)
{
subscriber.Recv(str);
if(!str.compare("END"))
{
cout << "sub recv over...!" << endl;
break;
}
cout << "subscriber recv = " << str << endl;
}
}
int main()
{
thread th0(Publisher);
thread th1(Subscriber);
th0.join();
th1.join();
return 0;
}
CC=g++
all:
$(CC) -std=c++11 -g -o TestZMQ_SUB test.cpp ZMQ_PipeSocket.h ZMQ_PipeSocket.cpp -lzmq -pthread
zmq pub syn
最新推荐文章于 2024-05-15 01:59:22 发布