首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >REQ/REP模式中的ZeroMQ FiniteStateMachineException

REQ/REP模式中的ZeroMQ FiniteStateMachineException
EN

Stack Overflow用户
提问于 2016-10-04 19:48:41
回答 1查看 3.4K关注 0票数 2

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

代码语言:javascript
复制
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"

使用C#库编写的客户端(REQ ):

代码语言:javascript
复制
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实现的REQ套接字交谈,Python实现已经过测试,工作正常。但是,C# reach在循环的第一次迭代中抛出以下错误,任何消息都不会到达服务器:

类型'NetMQ.FiniteStateMachineException‘的未处理异常发生在NetMQ.dll附加信息中: Req.XSend -无法发送另一个请求

堆栈跟踪:

代码语言:javascript
复制
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#代码是从文档库中提取的。是什么使代码抛出这个错误的?

我正在使用:

  • pyzmq 14.7
  • NetMQ 3.3.3.4
  • .NET 4.6

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

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

REP插座

代码语言:javascript
复制
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"

REQ插座

代码语言:javascript
复制
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);
            }
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-05 08:13:44

请求和响应套接字是状态机,您必须先发送请求,然后调用接收,您不能调用5个连续发送。

与之相反的是,你必须先呼叫接收。

如果一方只发送,另一方只接收,你可以使用推拉模式,而不是Req。你也可以使用交易商-路由器,如果需要,双方沟通。无论如何,Rep的用法似乎是不正确的。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39860614

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档