ZeroMq recv 不阻塞

ZeroMq recv not blocking

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

目前我的 'server' 是:

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# 'client' 推送 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(&message) 时,代码不会阻塞,而是会抛出异常,因为底层 zmq_msg_recv(...) returns 的值为 -1.

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

在套接字设置或我如何使用它来停止阻塞的 recv(...) 调用方面,我是否做错了什么?

您的问题是您无法连续接收 2 个具有 REQ-REP 模式的请求。

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

这里引用了 guide.

中针对您的确切问题的引述

The REQ-REP socket pair is in lockstep. The client issues zmq_send() and then zmq_recv(), in a loop (or once if that's all it needs). Doing any other sequence (e.g., sending two messages in a row) will result in a return code of -1 from the send or recv call. Similarly, the service issues zmq_recv() and then zmq_send() in that order, as often as it needs to.