我在我的网络层使用 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();
}
这是我的路由器代码(可以在不同的线程中运行,在这种情况下 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();
}
我在路由器上收到“HELLO”消息,我可以逐步通过 ROUTER 发送,一切似乎都已发送正常(即没有引发异常)但我从未在 REQ 套接字上收到消息,它将继续等待无限期。
根据 ZeroMQ 指南,我应该期望 ROUTER 收到以下消息:
REQ套接字发送
empty
HELLO
ROUTER接收
REQ
empty
HELLO
但我收到了
REQ
some binary message
empty
HELLO
然后我发送
REQ
empty
WORLD
我希望达到 REQ 为
empty
WORLD
如果我改为连接到 REP 套接字(使用简单的 REQ-REP 拓扑,一切正常)。
任何人都可以看到我遗漏/做错了什么吗?
最佳答案
我发现了问题。
基本上错误在于我发送定界符的方式
zmq::message_t zmqMsgReplyDelimiter(1);
memcpy ((void *) zmqMsgReplyDelimiter.data(), "\0", 1);
router.send(zmqMsgReplyDelimiter, ZMQ_SNDMORE);
应该是
zmq::message_t zmqMsgReplyDelimiter(0);
router.send(zmqMsgReplyDelimiter, ZMQ_SNDMORE);
关于c++ - ZMQ C++ Req 到路由器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21316083/