pyzmq公司接收插座()带有NOBLOCK标志behaviou

2024-05-16 02:36:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用pyzmq创建了简单的客户机/服务器。在

有一件事我不确定,.recv()没有接收到消息,即使它是从服务器发送的。它只是忽略它,抛出一个我觉得奇怪的错误。在

客户端.py

try:
    socket = context.socket(zmq.REQ)
    socket.connect("tcp://localhost:2222")
    print("Sending request")
    socket.send(b"send the message")
    message = socket.recv(flags=zmq.NOBLOCK)
    print("Received reply %s " % message)
except Exception as e:
    print(str(e))

服务器.py

^{pr2}$

我认为客户机应该接收Ack并打印它,而不是抛出异常。在

文件上说

With flags=NOBLOCK, this raises ZMQError if no messages have arrived

显然,服务器在收到消息后立即用“Ack”响应。在

信息就是错误

Resource temporarily unavailable


Tags: py服务器send消息message客户机错误socket
3条回答

Q : say the server is not up in that case the recv() in the client will be blocked forever which I don't want.

ZeroMQ是在分布式系统中进行智能信令/消息传递的极好框架

让我们描绘一个主要是非阻塞的操作方法的演示,并给出一些关于在进程终止之前如何获得资源以及如何优雅地释放资源的一些启示。在

也许阅读一下部分的主要概念差异也会有所帮助。在

希望您能喜欢这个和更深入的实验StackOverflow resources如何最好地利用ZeroMQ Zen of Zero的所有能力:

Server.py

 aContext     = zmq.Context()
 aLightHouse  =    aContext.socket( zmq.PUB )
 aRepSocket   =    aContext.socket( zmq.REP )
 aRepSocket.setsockopt(             zmq.LINGER,   0 )
 aRepSocket.setsockopt(             zmq.COMPLETE, 1 )
 aRepSocket.bind(                  "tcp://*:2222" )
 aLightHouse.bind(                 "tcp://*:3333" )
 aLightHouse.setsockopt(            zmq.LINGER,   0 )
 aLightHouse.setsockopt(            zmq.CONFLATE, 1 )
 aLightHouse_counter = 0
 #                              
 print( "INF: Server InS: ZeroMQ({0:}) going RTO:".format( zmq.zmq_version() )  )
 #                              
 while True:
    try:
        aLightHouse_counter += 1
        aLightHouse.send( "INF: server-RTO blink {0:}".format( repr( aLightHouse_counter ) ),
                           zmq.NOBLOCK
                           )
        if ( 0 < aRepSocket.poll( 0, zmq.POLLIN ) ):
            try:
                message = aRepSocket.recv(         zmq.NOBLOCK ); print( "INF: .recv()ed {0:}".format( message ) )
                pass;     aRepSocket.send( b"Ack", zmq.NOBLOCK ); print( "INF: .sent() ACK" )
            except:
                # handle EXC: based on ...
                print(  "EXC: reported as Errno == {0:}".format( zmq.zmq_errno() ) )
        else:
            # NOP / Sleep / do other system work-units to get processed during the infinite-loop
    except:
        # handle EXC:
        print(  "EXC: will break ... and terminate OoS ..." )
        break
#                              
print( "INF: will soft-SIG Server going-OoS..." )
aLightHouse.send(   "INF: server goes OoS ... " )
#                              
print( "INF: will .close() and .term() resources on clean & graceful exit..." )
Sleep( 0.987654321 )
aRepSocket.unbind(  "tcp://*:2222" )
aRepSocket.close()
aLightHouse.unbind( "tcp://*:3333" )
aLightHouse.close()
aContext.term()
#                              
print( "INF: over and out" )

Client.py

^{pr2}$

请记住,在并发环境中,不能保证独立进程的执行顺序。即使您正在立即响应server.py中的消息,在您调用socket.recv之前,响应可能无法到达接收套接字。{3当你的客户端需要回拨你的消息时,你需要回你的服务器,然后通过网络返回你的消息。通过网络发送消息的时间会很长,您将在socket.send之后立即调用socket.recv。在

因此,实际上,当您调用message = socket.recv(flags=zmq.NOBLOCK)时,客户机socket还没有从服务器接收到{},而且由于您使用的是NOBLOCK,因此会抛出一个错误,因为socket上没有收到任何消息。在

NOBLOCK在这种情况下可能不合适。您可以通过在sendrecv之间添加一个sleep调用来证明等待服务器响应的时间延迟确实是问题所在,但对于客户端代码来说,这不是一个好的解决方案。在

如果要在等待一定时间后退出,则应使用socket.pollhttps://pyzmq.readthedocs.io/en/latest/api/zmq.html#zmq.Socket.poll

您使用的是非阻塞模式,这意味着它将引发一个错误来通知您,消息无法处理,您应该稍后再试,但是如果您使用的是阻塞模式,它将阻止,直到对等方连接。在

这个答案来自here

基本上,如果你删除flags=zmq.NOBLOCK它就可以工作了。在

更新

如果你想使用非阻塞模式,你应该看看this

相关问题 更多 >