我不能确定错误出在哪里,但我正在尝试在 Python 客户端和 Chapel 服务器之间传递消息。客户端代码为
import zmq
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect("tcp://localhost:5555")
for request in range(10):
print("Sending request %s ..." % request)
socket.send(str("Yo"))
message = socket.recv()
print("OMG!! He said %s" % message)
Chapel 服务器是
use ZMQ;
var context: Context;
var socket = context.socket(ZMQ.REP);
socket.bind("tcp://*:5555");
while ( 1 < 2) {
var msg = socket.recv(string);
socket.recv(string);
writeln("got something");
socket.send("back from chapel");
}
这个消息看起来很普通,但我并没有真正理解它。
server.chpl:7: error: halt reached - Error in Socket.recv(string): Operation cannot be accomplished in current state
我想我正在发送/接收双方。原始教堂示例 on the Chapel site工作正常,但我在修改它时遇到问题。
更新
在 Chapel 团队的帮助下 this thread ,这现在有效。
client.py
import zmq
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect("tcp://localhost:5555")
for request in range(10):
message = "Hello %i from Python" % request
print("[Python] Sending request: %s" % message)
socket.send_string(message)
message = socket.recv_string()
print("[Python] Received response: %s" % message)
server.chpl
use ZMQ;
var context: Context;
var socket = context.socket(ZMQ.REP);
socket.bind("tcp://*:5555");
for i in 0..#10 {
var msg = socket.recv(string);
writeln("[Chapel] Received message: ", msg);
socket.send("Hello %i from Chapel".format(i));
}
请您参考如下方法:
@user3666197 的回答很好地讨论了 ZeroMQ 状态机,我认为问题在于 Chapel ZMQ 模块如何序列化和传输字符串。
Socket.send(string)和 Socket.recv(string) Chapel 中的方法通过发送两条消息来序列化一个字符串。这是打算匹配 ZeroMQ Guide's "Minor Note on Strings" 中的模式,然而,在实现时,这种序列化方案是不正确的,并且与某些 ZeroMQ 套接字模式不兼容。
要发送一个字符串,Chapel 发送一个多部分消息,两次调用 zmq_send():第一个字符串大小带有 ZMQ_SNDMORE 标志,然后是第二个使用字节缓冲区;接收工作类似。这意味着您对 socket.recv(string) 的一个调用实际上是对 zmq_recv( ) 引擎盖下。使用 REQ/REP 模式,这两个背靠背的 zmq_recv() 调用将 ZeroMQ 状态机置于无效状态,因此错误信息。
这绝对是 Chapel 的 ZMQ 模块的错误。
作为引用,我是(绝对不是没有错误的)Chapel ZMQ 模块的作者。
