2016-12-09 6 views
2

次のサーバーおよびクライアントコードは、the official tutorialのわずかに変更されたバージョンです。彼らの出力の私の解釈は、彼らが送受信するものは常に1バイトであるということです。これはどうしたらできますか?ZeroMQは常に1バイトを送信して取得します(cppzmqバインディングを使用)

server.cpp:

#include <zmq.hpp> 
#include <string> 
#include <iostream> 
#ifndef _WIN32 
#include <unistd.h> 
#else 
#include <windows.h> 
#define sleep(n) Sleep(n) 
#endif 

int main() { 
    zmq::context_t context(1); 
    zmq::socket_t socket(context, ZMQ_REP); 
    socket.bind("tcp://*:5555"); 
    while(true){ 
     zmq::message_t request; 
     int length=socket.recv(&request); 
     if(length >= 0) 
      std::cout << length << " bytes received:" << std::string((char*)request.data(),length) << ":" << std::endl; 
     sleep(1); 
     zmq::message_t reply(5); 
     memcpy(reply.data(), "World", 5); 
     socket.send(reply); 
    } 
    return 0; 
} 

サーバーouputを:

1 bytes received:H: 

client.cpp:

#include <zmq.hpp> 
#include <string> 
#include <iostream> 
int main() 
{ 
    zmq::context_t context(1); 
    zmq::socket_t socket(context,ZMQ_REQ); 
    socket.connect ("tcp://localhost:5555"); 
    zmq::message_t request(5); 
    memcpy(request.data(),"Hello",5); 
    std::cout << socket.send(request) << " bytes sent." << std::endl; 
    zmq::message_t reply; 
    int length=socket.recv(&reply); 
    if(length >= 0) 
     std::cout << length << " bytes received:" << std::string((char*)request.data(),length) << ":" << std::endl; 
    return 0; 
} 

クライアント出力:

1 bytes sent. 
1 bytes received:H: 

このような奇妙な結果が出たとき、私はZeroMQの使い方を誤解している可能性があると考え始めます。私はこの「 Minor Note on Strings」を繰り返し読んでいます。

ゼロサイズは送信するデータについて、そのサイズ(バイト数)以外は何も分かりません。つまり、アプリケーションが安全にフォーマットできるようにすることで、アプリケーションはそれを読み取ることができます。それでは、ZeroMQ文字列の長さが指定され、末尾のヌルなしワイヤー上で送信されるルールを確立しましょう

:この文が続いている

、。

これらの2つの段落は矛盾しています。 ZeroMQが送信するコンテンツは何ですか?

+0

C++を使用している場合は、なぜC言語のように書いていますか? 'zmq :: message_t {" hello "、5}'(C++ 11より古いものを使用している場合は中カッコをかっこに置き換えます) – Olipro

+0

@olipro見つからないバージョン4.0.5の 'zmq.hpp'ファイルの' zmq :: message_t(char *、size_t) 'のようなコンストラクタです。 –

答えて

1

ZMQは生のバイトを送受信できます。代わりにzmq::message_tを使用することをお勧めします。なぜなら、あなたのために多くのエッジケースを処理し、一般的には操作しやすいからです。 recv in zmq.hpp (link)の実装で

ルック:

inline bool recv (message_t *msg_, int flags_ = 0) 
    { 
     int nbytes = zmq_msg_recv (&(msg_->msg), ptr, flags_); 
     if (nbytes >= 0) 
      return true; 
     if (zmq_errno() == EAGAIN) 
      return false; 
     throw error_t(); 
    } 

それはtrueを返し、あなたのlength1に等しい理由です。

あなたが引用した段落は矛盾していません。受け取ったデータがNULLで終了していると仮定するべきではないと言います。つまり、に電話をかけてはならないということです.printfは割り当てられていないメモリにアクセスしようとします。ただし、代わりにprintf("%.*s", (int)request.size(), request.data())を使用できます。

結局のところ、ZMQは送信するように送信するため、基本的には何かを送信してメッセージを受信して​​解凍します(たとえば、複数の文を1つのzmq::message_tで送信し、\0これらの文の間の区切り文字として)。

2

boolを返す関数を使用しているようです。したがってtrue1に変換されます。

これは、1バイトを受信して​​送信したと思われる理由を説明しています。 message_tオブジェクトでsize()に電話することをおすすめします。

2

ありがとうございました! 私が過負荷size_t send (const void *buf_, size_t len_, int flags_ = 0)代わりのbool send (message_t &msg_, int flags_ = 0)を呼び出すと、コードC.より少しC++は、この例外を処理しない作業バージョンである可能だと思う:

server.cpp:

// Hello World server in C++ 
// Binds REP socket to tcp://*:5555 
// Expects "Hello" from client, replies with "World" 
// 
#include <zmq.hpp> 
#include <string> 
#include <iostream> 
#ifndef _WIN32 
#include <unistd.h> 
#else 
#include <windows.h> 
#define sleep(n) Sleep(n) 
#endif 

int main() { 
    zmq::context_t context(1); 
    zmq::socket_t socket(context, ZMQ_REP); 
    socket.bind("tcp://*:5555"); 
    while(true){ 
     zmq::message_t request; 
     if(socket.recv(&request)) 
      std::cout << request.size() << " bytes received:" << std::string((char*)request.data(),request.size()) << std::endl; 
     sleep(1); 
     std::cout << socket.send("world",5,0) << " bytes replied" << std::endl; 
    } 
    return 0; 
} 

client.cpp:

// Hello World client in C++ 
// Connects REQ socket to tcp://localhost:5555 
// Sends "Hello" to server, expects "World" back 
// 
#include <zmq.hpp> 
#include <string> 
#include <iostream> 

int main() 
{ 
    zmq::context_t context(1); 
    zmq::socket_t socket(context,ZMQ_REQ); 
    socket.connect ("tcp://localhost:5555"); 
    std::cout << socket.send("Hello",5,0) << " bytes sent." << std::endl; 
    zmq::message_t reply; 
    if(socket.recv(&reply)) 
     std::cout << reply.size() << " bytes received:" << std::string((char*)reply.data(),reply.size()) << std::endl; 
    return 0; 
} 
関連する問題