这是我在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
的test.txt
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
解决方法:
好吧,你提出了我的首选解决方案,即只需将整个事件作为单个消息发送,必要时使用单独的帧.也就是说,它允许您只发送一个回复的原因是因为您正在使用REQ-REP套接字对,并且在使用这样的一对时,您必须遵循简单的“请求 – 回复 – 请求 – 回复”模式.每个通信必须以一个请求开始,下一个消息必须是一个回复,下一个请求等.
要解决此问题,您有以下几种选择:
>正如您所做的那样,将您要发送的所有内容打包在一条消息中.在你的情况下,只要没有阻止它的约束,这将是首选选项,因为所有数据实际上是一个逻辑消息,来自一个逻辑文件,并且它将全部组成一个逻辑块我假设接收端的数据.
>如果你想保留REQ-REP套接字对,那么你可以发送请求,然后发送回复,然后你的下一个请求就可以是“更多”或类似的东西,然后是下一条数据,继续请求“更多”,直到您的客户回复“DONE”之类的内容,此时您知道您拥有所有数据并且可以退出请求更多数据.
>或者,如果您希望能够对单个请求进行多次回复,或者在收到回复之前多次请求,那么您将需要使用ROUTER-DEALER套接字对而不是REQ-REP.在这种情况下,您的DEALER套接字将取代您的REQ套接字,而ROUTER将取代REP.如果您遇到如何实施ROUTER-DEALER,请查看手册并提出新问题.