这是我在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
答案 0 :(得分:4)
以下是我提出的解决方案......以防万一有人可能需要类似情况的帮助。 我们的想法是将所有行打包在一条消息中并将其发送回客户端。 似乎它的工作原理是,对于客户端发出的每个请求,服务器都需要做出回复并且只需要一个回复。至少我就是这样看的..
替换服务器端的代码
# 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....
现在这已经解决了,接下来的问题是:客户端需要发送什么样的请求才能以逐行方式接受来自服务器的响应。 如果我有解决方案,我会更新回复,或者您可以随意参与。
答案 1 :(得分:3)
好吧,你想出了我的首选解决方案,就是将整个事件作为单个消息发送,必要时使用单独的帧。也就是说,它允许您只发送一个回复的原因是因为您正在使用REQ-REP
套接字对,并且当使用这样的一对时,您必须遵循一个简单的“请求 - 回复请求回复“模式。每个通信必须以一个请求开始,下一个消息必须是一个回复,下一个请求等等。
要解决此问题,您有以下几种选择:
REQ-REP
套接字对,那么您可以发送请求,然后回复,然后您的下一个请求可以是“更多”或类似的东西,然后是下一个数据,并继续请求“更多”,直到您的客户回复“DONE”之类的内容,此时您知道您拥有所有数据并且可以退出请求更多数据。ROUTER-DEALER
套接字对而不是{{1} }。在这种情况下,您的REQ-REP
套接字将取代DEALER
套接字,REQ
代替ROUTER
。如果您遇到如何实施REP
。