这是我第一次接触Python下的ZMQ,我希望服务器在收到客户端的请求时发送多行。 我在服务器端添加到 ZMQ 提供的示例中的代码是:
with open("test.txt", 'r') as f:
for line in f:
socket.send_string(line.rstrip("\n"))
问题是如何让服务器发送所有行或者如何让客户端不先于服务器发送请求 完成发送来自
test.txt
的所有行
import zmq
context = zmq.Context()
print("Connecting to hello world server")
socket = context.socket(zmq.REQ)
socket.connect("tcp://localhost:5555")
for request in range(10):
print("Sending request %s" % request)
socket.send(b"Hello")
message = socket.recv()
print("Received reply %s [ %s ]" % (request, message))
import time
import zmq
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:5555")
while True:
# Wait for next request from client
message = socket.recv()
print("Received request: %s" % message)
# Do some 'work'
time.sleep(1)
# Send reply back to client
with open("test.txt", 'r') as f:
for line in f:
socket.send_string(line.rstrip("\n"))
Connecting to hello wolrd server
Sending request 0
Received reply 0 [ This is test line 1 ]
Sending request 1
这是它停止的地方,因为服务器生成了如下所示的错误:
line 324, in send_string
return self.send(u.encode(encoding), flags=flags, copy=copy)
File "socket.pyx", line 571, in zmq.backend.cython.socket.Socket.send (zmq/backend/cython/socket.c:5319)
File "socket.pyx", line 618, in zmq.backend.cython.socket.Socket.send (zmq/backend/cython/socket.c:5086)
File "socket.pyx", line 181, in zmq.backend.cython.socket._send_copy (zmq/backend/cython/socket.c:2081)
File "checkrc.pxd", line 21, in zmq.backend.cython.checkrc._check_rc (zmq/backend/cython/socket.c:6032)
zmq.error.ZMQError: Operation cannot be accomplished in current state
Process finished with exit code 1
This is test line 1
This is test line 2
This is test line 3
This is test line 4
This is test line 5
我的解决方案... 这个想法是将所有行打包在一条消息中并将其发送回客户端。
替换服务器端代码
# Send reply back to client
with open("test.txt", 'r') as f:
for line in f:
socket.send_string(line.rstrip("\n"))
与:
# Send reply back to client
with open("test.txt", 'r') as f:
message = '%s' % f.readlines()
print(message)
print(type(message))
socket.send_string(message)
Connecting to hello world server
Sending request 0
Received reply 0 [ ['This is test line 1\n', 'This is test line 2\n', 'This is test line 3\n', 'This is test line 4\n', 'This is test line 5\n', 'This is test line 6\n', 'This is test line 7\n', 'This is test line 8\n', 'This is test line 9\n', 'This is test line 10\n', '\n'] ]
Sending request 1
Received reply 1 [ ['This is test line 1\n', 'This is test line 2\n', 'This is test line 3\n', 'This is test line 4\n', 'This is test line 5\n', 'This is test line 6\n', 'This is test line 7\n', 'This is test line 8\n', 'This is test line 9\n', 'This is test line 10\n', '\n'] ]
....
....
and so on up to 10 requests
Received request: Hello
['This is test line 1\n', 'This is test line 2\n', 'This is test line 3\n', 'This is test line 4\n', 'This is test line 5\n', 'This is test line 6\n', 'This is test line 7\n', 'This is test line 8\n', 'This is test line 9\n', 'This is test line 10\n', '\n']
<type 'str'>
Received request: Hello
['This is test line 1\n', 'This is test line 2\n', 'This is test line 3\n', 'This is test line 4\n', 'This is test line 5\n', 'This is test line 6\n', 'This is test line 7\n', 'This is test line 8\n', 'This is test line 9\n', 'This is test line 10\n', '\n']
<type 'str'>
....
....
....
and so on....
现在这个问题已经解决了,下一个问题是:客户端需要发送什么样的请求才能以逐行方式接受服务器的响应。 如果我有解决方案,我会更新回复,或者您可以随意参与您自己的解决方案。
好吧,您提出了我首选的解决方案,即将整个内容作为单个消息发送,必要时使用单独的帧。 也就是说,它只允许您发送单个回复的原因是因为您使用的是
REQ-REP
套接字对,并且在使用这样的套接字对时,您 must 遵循简单的“请求-回复-请求-回复”模式。 每次通信必须以一个请求开始,下一条消息必须是一个回复,然后是下一个请求,等等
要解决此问题,您有多种选择:
REQ-REP
套接字对,那么你可以发送一个请求,然后回复,然后你的下一个请求可以是“MORE”或类似的东西,然后是下一条数据,然后只需继续请求“更多”,直到您的客户回复“完成”之类的内容,此时您就知道您拥有所有数据并且可以停止请求更多。ROUTER-DEALER
套接字对而不是 REQ-REP
。 在这种情况下,您的 DEALER
插槽将取代您的 REQ
插槽,并且 ROUTER
将取代 REP
。 如果您在如何实施方面遇到困难,请查看手册并提出新问题ROUTER-DEALER
。