2014-01-23 46 views
5

我正在为我的网络层使用ZeroMQ,到目前为止,除了ROUTER套接字之外,所有工作都可行。特别是我在ROUTER上收到了预期的消息,但是当我尝试将一个答案发回给我的REQ套接字时,该消息从未收到。ZMQ C++请求路由器问题

这是我写的一个比较简单的测试,它试图向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”的消息,我可以通过路由器发送步骤,一切似乎要发送的好(即正在升起也不例外),但我从来没有在收到消息REQ插座将会无限期地等待。

按照ZeroMQ指南我应该期待路由器收到以下消息:

的REQ插座发送

empty 
HELLO 

路由器接收

REQ 
empty 
HELLO 

,但我收到

REQ 
some binary message 
empty 
HELLO 

我送

REQ 
empty 
WORLD 

,我会希望在REQ如约到达

empty 
WORLD 

如果我连接到插座REP代替(使用简单的REQ-REP拓扑一切工作正常)。

任何人都可以看到我失踪/做错了吗?

+0

这可能是别人犯同样的错误是有用的,但你应该现在缩短的问题示例代码不是必需的,并且对于实际问题更具体。 – JSON

回答

5

我发现了这个问题。

基本错误是怎么发出的分隔符​​

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);