【问题标题】:Simple client/server ZMQ in Python to send multiple lines per requestPython中的简单客户端/服务器ZMQ,每个请求发送多行
【发布时间】:2014-07-14 08:49:39
【问题描述】:

这是我第一次接触 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

【问题讨论】:

    标签: python zeromq pyzmq


    【解决方案1】:

    这是我想出的解决方案……以防万一有一天,有人可能在类似情况下需要帮助。 这个想法是将所有行打包在一条消息中并将其发送回客户端。 似乎它的工作原理是对于客户端发出的每个请求,服务器都需要做出回复并且只有一个回复。至少我是这么看的..

    在服务器端替换代码

    #  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....
    

    现在问题解决了,下一个问题是:客户端需要发送什么样的请求才能以逐行方式接受来自服务器的响应。 如果我有解决方案,我会更新回复,或者您可以随意参与。

    【讨论】:

      【解决方案2】:

      嗯,你想出了我首选的解决方案,也就是说,将整个内容作为单个消息发送,必要时使用单独的帧。也就是说,它只允许您发送一个回复的原因是因为您使用的是REQ-REP 套接字对,并且当使用这样的一对时,您必须遵循一个简单的“request-reply-请求-回复”模式。每次通信必须从一个请求开始,下一条消息必须是一个回复,下一个是请求,等等。

      要解决此问题,您有多种选择:

      • 和您一样,将您想要发送的所有内容打包成一条消息。在您的情况下,只要没有阻止它的约束,这将是首选选项,因为所有数据实际上都是一个逻辑消息,来自一个逻辑文件,并且它们都将被组合成一个逻辑片段接收端的数据,我假设。
      • 如果你想保留REQ-REP套接字对,那么你可以发送一个请求,然后是一个回复,然后你的下一个请求可以只是“MORE”之类的,然后是下一条数据,然后继续请求“更多”,直到您的客户回复“完成”之类的内容,此时您知道您拥有所有数据并且可以停止请求更多。
      • 或者,如果您希望能够对单个请求进行多次回复,或者在收到回复之前多次请求,那么您将希望使用ROUTER-DEALER 套接字对而不是REQ-REP。在这种情况下,您的DEALER 套接字将代替您的REQ 套接字,而ROUTER 将代替REP。如果您对如何实施 ROUTER-DEALER 感到困惑,请查看手册并提出一个新问题。

      【讨论】:

        猜你喜欢
        • 2019-09-19
        • 2010-10-26
        • 1970-01-01
        • 2020-07-15
        • 2015-06-15
        • 1970-01-01
        • 2021-12-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多