c# - REQ/REP 模式中的 ZeroMQ FiniteStateMachineException

标签 c# python zeromq pyzmq netmq

我有两个简单的组件,它们应该使用 REQ/REP ZeroMQ 模式相互通信。 服务器(REP 套接字)是使用 pyzmq 在 Python 中实现的:

import zmq

def launch_server():
    print "Launching server"
    with zmq.Context.instance() as ctx:
        socket = ctx.socket(zmq.REP)
        socket.bind('tcp://127.0.0.1:5555')

        while True:
            msg = socket.recv()
            print "EOM\n\n"

使用 NetMQ 库用 C# 编写的客户端(REQ 套接字):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NetMQ;


namespace PyNetMQTest
{
    class Program
    {

        static void Main(string[] args)
        {
            string msg;
            NetMQ.Sockets.RequestSocket socket = new NetMQ.Sockets.RequestSocket();
            socket.Connect("tcp://127.0.0.1:5555");
            for(int i=0; i<5; i++)
                socket.SendFrame("test_"+i);
        }
    }
}

Python 服务器实现已经过测试,可以通过与使用 Python 实现的 REQ 套接字对话来正常工作。但是 C# REQ 套接字在循环的第一次迭代中抛出以下错误,并且没有消息到达服务器:

NetMQ.dll 中出现类型为“NetMQ.FiniteStateMachineException”的未处理异常 附加信息:Req.XSend - 无法发送另一个请求

堆栈跟踪:

at NetMQ.Core.Patterns.Req.XSend(Msg& msg)
   at NetMQ.Core.SocketBase.TrySend(Msg& msg, TimeSpan timeout, Boolean more)
   at NetMQ.NetMQSocket.TrySend(Msg& msg, TimeSpan timeout, Boolean more)
   at NetMQ.OutgoingSocketExtensions.Send(IOutgoingSocket socket, Msg& msg, Boolean more)
   at NetMQ.OutgoingSocketExtensions.SendFrame(IOutgoingSocket socket, String message, Boolean more)
   at PyNetMQTest.Program.Main(String[] args) in d:\users\emes\documents\visual studio 2015\Projects\PyNetMQ Test\PyNetMQTest\Program.cs:line 20
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

这些是我使用 ZMQ 的第一步,C# 代码取自库 documentation . 是什么导致代码抛出此错误?

我正在使用:

  • pyzmq 14.7
  • NetMQ 3.3.3.4
  • .NET 4.6

====================== 解决方案 ===================== =

正如@somdoron 在他的回答中所解释的那样,原因是两个套接字都需要经过完整的发送/接收周期才能被重新使用。 事实上,在 python 中实现的 REP 套接字也没有改变它的状态,所以错误出现在 python 和 C# 代码中。这是固定代码:

REP 套接字

import zmq

def launch_server():
    print "Launching server"
    with zmq.Context.instance() as ctx:
        socket = ctx.socket(zmq.REP)
        socket.bind('tcp://127.0.0.1:5555')

        while True:
            msg = socket.recv()
            socket.send("reply to "+msg)
            print "EOM\n\n"

请求套接字

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NetMQ;


namespace PyNetMQTest
{
    class Program
    {

        static void Main(string[] args)
        {

            NetMQ.Sockets.RequestSocket socket = new NetMQ.Sockets.RequestSocket();
            socket.Connect("tcp://127.0.0.1:5555");

            string msg, reply;

            while (true)
            {
                Console.WriteLine("Type message: ");
                msg = Console.ReadLine();
                Console.WriteLine("Sending : " + msg);
                socket.SendFrame(msg);
                reply = socket.ReceiveFrameString();
                Console.WriteLine("Received: " + reply + Environment.NewLine);
            }
        }
    }
}

最佳答案

Request和Response套接字是状态机,Request必须先Send再调用Receive,不能连续调用5次Send。

与 Response 相反,您必须先调用 Receive。

如果一侧仅发送而另一侧仅接收,您可以使用推拉模式而不是 Req-Rep。如果需要双向通信,您也可以使用 Dealer-Router。无论如何,似乎 Req-Rep 的用法不正确。

关于c# - REQ/REP 模式中的 ZeroMQ FiniteStateMachineException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39860614/

相关文章:

python - 使用 python 通过网络抓取来提取表

go - ZeroMQ 知道请求来自哪个 go routine

c# - ToDictionary 没有按预期工作

c# - 根据另一个数组中的条件对一个数组求平均值

c# - 如何在 Javascript 中显示 C# 模型列表的某一方面?

c++ - 带有 msgpack 的 ZeroMQ 在 C++ 中抛出无效参数错误

c - C 语言中的 Zeromq pub/sub 示例 (libzmq)

C# - 使用 File.WriteAllLines

Python itertools.combinations() 内存问题

python - 矩阵线性组合的系数