【问题标题】:ZeroMq recv not blockingZeroMq recv 不阻塞
【发布时间】:2016-12-01 03:13:26
【问题描述】:

尽管我的背景是 C#,但我正在尝试为工作项目学习 ZeroMq,并且在最简单的测试中,我似乎遇到了一个问题,即 socket.recv(...) 调用将阻止第一个收到的消息,但之后这会引发异常,因为接收到的数据量为 -1。

目前我的“服务器”是:

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#“客户端”推送 1 位数据:

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(&amp;message) 时,代码不会阻塞而是会抛出异常,因为底层的zmq_msg_recv(...) 返回值-1。

我不确定为什么会发生这种情况,我不明白为什么它会收到另一条消息,因为我知道这个端口上没有其他东西。我遇到的唯一事情是调用zmq_msg_close(...),但这应该作为message_t 析构函数的一部分调用,我已经确认了这一点。

在套接字设置或我如何将其用于recv(...) 调用以停止阻塞方面,我做错了什么吗?

【问题讨论】:

  • '@' 字符有什么作用?我的代码中没有。
  • 啊,我明白了,它使字符串成为文字。所以它不能使用转义字符'\'

标签: c# c++ zeromq


【解决方案1】:

您的问题是您无法使用 REQ-REP 模式连续收到 2 个请求。

在请求-回复模式中,每个请求都需要回复。您的客户端需要阻止,直到收到对其第一个请求的回复。此外,您的服务器需要在处理新请求之前回复请求。

这里引用了来自guide 的确切问题。

REQ-REP 套接字对步调一致。客户端发出 zmq_send() 然后是 zmq_recv(),在一个循环中(或者一次,如果这就是它所需要的)。正在做 任何其他序列(例如,连续发送两条消息)将导致 在 send 或 recv 调用的返回码 -1 中。同样, 服务按顺序发出 zmq_recv() 然后 zmq_send() ,通常 根据需要。

【讨论】:

  • 好吧,只是表明我应该注意文档的全部部分。在处理完收到的消息后,我通过发送一条空消息设法解决了我的问题。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-11
  • 1970-01-01
  • 2013-04-03
相关资源
最近更新 更多