2014-01-23 72 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);