EmE*_*mEs 2 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"
Run Code Online (Sandbox Code Playgroud)
使用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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
通过与使用Python实现的REQ套接字进行通讯,Python Server实现已经过测试,可以正常工作。但是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()
Run Code Online (Sandbox Code Playgroud)
这是我使用ZMQ的第一步,C#代码来自库文档。是什么使代码引发此错误?
我在用:
=====================解决方案====================
正如@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"
Run Code Online (Sandbox Code Playgroud)
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)
{
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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Request和Response套接字是状态机,使用Request时,必须先发送,然后再调用Receive,才能连续调用5个Send。
与Response相反,您必须先致电Receive。
如果一侧仅发送而另一侧仅接收,则可以使用推拉模式而不是Req-Rep。如果需要双向通讯,也可以使用Dealer-Router。无论如何,似乎Req-Rep的用法不正确。
| 归档时间: |
|
| 查看次数: |
1694 次 |
| 最近记录: |