我正在使用ZeroMQ作为我的网络层,到目前为止一切正常,除了ROUTER套接字.特别是我在ROUTER上收到了预期的消息但是当我尝试将回复发送回我的REQ套接字时,从未收到消息.
这是我写的一个相对简单的测试,它试图向ROUTER发送一个"HELLO"消息,并期望一条消息回来.
这里客户端代码:
try
{
zmq::context_t myContext;
zmq::socket_t reqSocket(myContext, ZMQ_REQ);
reqSocket.setsockopt(ZMQ_IDENTITY, "REQ", 3);
reqSocket.connect(gpRouterAddress);
//request delimiter
zmq::message_t zmqMsgReqDelimiter(1);
memcpy ((void *) zmqMsgReqDelimiter.data(), "\0", 1);
reqSocket.send(zmqMsgReqDelimiter, ZMQ_SNDMORE);
//some message
zmq::message_t reqMsg(5);
memcpy ((void *) reqMsg.data(), "HELLO", 5);
reqSocket.send(reqMsg, 0);
int rcvMore = 0;
size_t sizeInt = sizeof(int);
bool bRcvMore = true;
std::vector<std::string> history;
while(bRcvMore)
{
zmq::message_t zmqMsg;
reqSocket.recv(&zmqMsg, rcvMore);
const char* pMsgStr = static_cast<char*>(zmqMsg.data());
history.push_back(pMsgStr);
reqSocket.getsockopt(ZMQ_RCVMORE, &rcvMore, &sizeInt);
bRcvMore = (rcvMore == 1);
}
}
catch (zmq::error_t error)
{
std::string errorStr = error.what();
}
Run Code Online (Sandbox Code Playgroud)
这是我的路由器代码(可以在不同的线程中运行,在这种情况下,theContext将与上面的代码中的"myContext"相同)或完全不同的应用程序:
try
{
zmq::context_t theContext;
zmq::socket_t router (theContext, ZMQ_ROUTER);
int value = 1;
router.setsockopt(ZMQ_ROUTER_MANDATORY, &value, sizeof(int));
router.setsockopt(ZMQ_IDENTITY, "ROUT", 4);
router.bind(gpRouterAddress);
zmq::message_t zmqMsgInternalAddress;
router.recv(&zmqMsgInternalAddress, 0);
const char* pAddressStr = static_cast<char*>(zmqMsgInternalAddress.data());
zmq::message_t zmqMsgDelimiter;
router.recv(&zmqMsgDelimiter, ZMQ_RCVMORE);
const char* pDelimiterStr = static_cast<char*>(zmqMsgDelimiter.data());
int rcvMore = 0;
size_t sizeInt = sizeof(int);
bool bRcvMore = true;
router.getsockopt(ZMQ_RCVMORE, &rcvMore, &sizeInt);
bRcvMore = (rcvMore == 1);
std::vector<std::string> history;
while(bRcvMore)
{
zmq::message_t zmqMsg;
router.recv(&zmqMsg, rcvMore);
const char* pMsgStr = static_cast<char*>(zmqMsg.data());
history.push_back(pMsgStr);
router.getsockopt(ZMQ_RCVMORE, &rcvMore, &sizeInt);
bRcvMore = (rcvMore == 1);
}
//reply address
size_t len = strlen(pAddressStr) - 1; //if I don't subtract 1 char here, an exception will be raised
zmq::message_t replyAddress(len);
memcpy ((void *) replyAddress.data(), pAddressStr, len);
router.send(replyAddress, ZMQ_SNDMORE);
//reply delimiter
zmq::message_t zmqMsgReplyDelimiter(1);
memcpy ((void *) zmqMsgReplyDelimiter.data(), "\0", 1);
router.send(zmqMsgReplyDelimiter, ZMQ_SNDMORE);
//some message
zmq::message_t replyMsg(5);
memcpy ((void *) replyMsg.data(), "WORLD", 5);
router.send(replyMsg, 0);
}
catch (zmq::error_t error)
{
std::string errorStr = error.what();
}
Run Code Online (Sandbox Code Playgroud)
我在路由器上收到"HELLO"消息,我可以单步执行ROUTER发送,一切似乎都被发送好了(即没有异常被提出)但我从未在REQ套接字上收到一条消息,它将一直无限期地等待.
根据ZeroMQ指南,我应该期望ROUTER收到以下消息:
REQ套接字发送
empty
HELLO
Run Code Online (Sandbox Code Playgroud)
ROUTER收到
REQ
empty
HELLO
Run Code Online (Sandbox Code Playgroud)
但我收到了
REQ
some binary message
empty
HELLO
Run Code Online (Sandbox Code Playgroud)
我送了
REQ
empty
WORLD
Run Code Online (Sandbox Code Playgroud)
我希望能够到达REQ
empty
WORLD
Run Code Online (Sandbox Code Playgroud)
如果我改为连接到REP套接字(使用简单的REQ-REP拓扑,一切正常).
任何人都可以看到我遗失/做错了什么?
我发现了这个问题.
基本上错误在于我如何发送分隔符
zmq::message_t zmqMsgReplyDelimiter(1);
memcpy ((void *) zmqMsgReplyDelimiter.data(), "\0", 1);
router.send(zmqMsgReplyDelimiter, ZMQ_SNDMORE);
Run Code Online (Sandbox Code Playgroud)
它应该是
zmq::message_t zmqMsgReplyDelimiter(0);
router.send(zmqMsgReplyDelimiter, ZMQ_SNDMORE);
Run Code Online (Sandbox Code Playgroud)