2016-11-30 10 views
1

私の背景はC#ですが、仕事でプロジェクトのためにZeroMqを学ぼうとしていますが、もっとも簡単なテストでは、最初に受信したメッセージに対してsocket.recv(...)コールがブロックされるという問題があるようです。受信したデータの量が-1であるため、例外がスローされます。ZeroMq recv not blocking

現在、私の「サーバー」は次のとおりです。

zmq::context_t context(1); 
zmq::socket_t socket(context, ZMQ_REP); 
socket.bind("tcp://127.0.0.1:5555"); 

while (true) 
{ 
    zmq::message_t message; 
    if (socket.recv(&message)) 
    { 
     auto str = std::string(static_cast<char*>(message.data()), message.size()); 
     printf("Receieved: %s\n", str.c_str()); 
    } 
} 

これはZeroMqドキュメント内の最初の例でサーバを次の中から、基本的です。

私はこのコードを使用してC#の「クライアント」からのデータのビットをプッシュしています:

using (var context = new ZContext()) 
using (var requester = new ZSocket(context, ZSocketType.REQ)) 
{ 
    requester.Connect(@"tcp://127.0.0.1:5555"); 
    requester.Send(new ZFrame(@"hello")); 

    requester.Disconnect(@"tcp://127.0.0.1:5555"); 
} 

は今、私は、サーバーを起動し、クライアントを起動します。私は最初のメッセージを正しく受信し、これを正しく印刷することができます。 しかし、 socket.recv(&message)を再び押すと、コードはブロックされませんが、基底の zmq_msg_recv(...)が-1を返すため、代わりに例外がスローされます。

なぜこのようなことが起こっているのかよくわからないのですが、私はこのポートに他に何もないことを知っているので、なぜ別のメッセージを期待しているのかわかりません。私が遭遇した唯一の事はzmq_msg_close(...)ですが、これはmessage_tデストラクタの一部として呼び出す必要があります。これは私が確認したものです。

ソケット設定の点で私が間違っていることは何ですか、または私がrecv(...)呼び出しをブロックするのに使用する方法はありますか?

+0

「@」の文字は何をしますか?私は自分のコードでそれを持っていません。 – ComradeJoecool

+0

ああ、私はそれが文字列リテラルを参照してください。だから、エスケープ文字 ''\'を使うことはできません。 – ComradeJoecool

答えて

4

REQ-REPパターンで2つの要求を連続して受信できないという問題があります。

要求応答パターンでは、各要求で応答が要求されます。クライアントは、最初のリクエストに対する返信を受信するまでブロックする必要があります。また、サーバーは新しい要求を処理する前に要求に応答する必要があります。

ここには、guideからの正確な問題が引用されています。

REQ-REPソケットペアはロックステップにあります。クライアントはzmq_send() を発行し、次にzmq_recv()をループで発行します(必要な場合は1回)。 他のシーケンス(たとえば、2つのメッセージを連続して送信する)を実行すると、sendまたはrecvコールから戻りコード-1で が返されます。同様に、 サービスは、zmq_recv()、zmq_send()の順に発行します。多くの場合、 が必要です。

+0

文書の全面的な部分に注意を払う必要があることを示しています。受信メッセージの処理が終了したら空のメッセージを送信して問題を解決しました。ありがとう。 –