Python 如何在非zmq套接字和pyzmq之间进行调整?

Python 如何在非zmq套接字和pyzmq之间进行调整?,python,zeromq,pyzmq,Python,Zeromq,Pyzmq,我想在非ZMQ套接字和ZMQ套接字之间编写一个桥接 客户端代码: import socket if __name__ == '__main__': HOST = "localhost" PORT = 8888 BUFFER = 4096 try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print sock ret = sock.conn

我想在非ZMQ套接字和ZMQ套接字之间编写一个桥接

客户端代码:

import socket

if __name__ == '__main__':

    HOST = "localhost"
    PORT = 8888
    BUFFER = 4096

    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        print sock
        ret = sock.connect((HOST, PORT))
        print ret

        ret = sock.send('hello, tcpServer!')
        print ret
        recv = sock.recv(BUFFER)
        print ('[tcpServer siad]: %s' % recv)
        sock.close()
    except e:
        print e
代理代码,使用此代理将请求发送到ZMQ_REP服务器

import zmq

if __name__ == '__main__':

    context = zmq.Context()
    socket = context.socket(zmq.STREAM)
    socket.bind("tcp://*:8888")

    socket_req = context.socket(zmq.REQ)
    socket_req.connect("tcp://localhost:5556")

    while True:
        clientid, message = socket.recv_multipart();

        print("id: %r" % clientid)
        print("request:",message.decode('utf8'))

        socket_req.send(clientid, flags=zmq.SNDMORE, copy=False)
        socket_req.send("Hi", copy=False)

        clientid, message = socket_req.recv_multipart()


        print("id: %r" % clientid)
        print("request:",message.decode('utf8'))
ZMQ_代表服务器代码:

import zmq
import time
import sys


if __name__ == '__main__':

    port = '5556'
    if len(sys.argv) > 1:
        port = sys.argv[1]
        int(port)

    context = zmq.Context()
    socket = context.socket(zmq.REP)
    socket.bind("tcp://*:%s" % port)

    while True:
        message = socket.recv()
        print "Received request: ", message
        time.sleep(1)
        socket.send("world from %s" % port)
REQ get错误:

Received request:  k
Traceback (most recent call last):
  File "req_server.py", line 21, in <module>
    socket.send("world from %s" % port)
  File "zmq/backend/cython/socket.pyx", line 574, in zmq.backend.cython.socket.Socket.send (zmq/backend/cython/socket.c:5434)
  File "zmq/backend/cython/socket.pyx", line 621, in zmq.backend.cython.socket.Socket.send (zmq/backend/cython/socket.c:5196)
  File "zmq/backend/cython/socket.pyx", line 181, in zmq.backend.cython.socket._send_copy (zmq/backend/cython/socket.c:2035)
  File "zmq/backend/cython/checkrc.pxd", line 21, in zmq.backend.cython.checkrc._check_rc (zmq/backend/cython/socket.c:6248)
zmq.error.ZMQError: Operation cannot be accomplished in current state
收到的请求:k
回溯(最近一次呼叫最后一次):
文件“req_server.py”,第21行,在
socket.send(“来自%s的世界”%port)
文件“zmq/backend/cython/socket.pyx”,第574行,位于zmq.backend.cython.socket.send(zmq/backend/cython/socket.c:5434)中
文件“zmq/backend/cython/socket.pyx”,第621行,位于zmq.backend.cython.socket.send(zmq/backend/cython/socket.c:5196)中
文件“zmq/backend/cython/socket.pyx”,第181行,在zmq.backend.cython.socket中。发送副本(zmq/backend/cython/socket.c:2035)
文件“zmq/backend/cython/checkrc.pxd”,第21行,在zmq.backend.cython.checkrc.\u check\u rc(zmq/backend/cython/socket.c:6248)中
zmq.error.ZMQError:无法在当前状态下完成操作

最好的猜测是,它没有正确注册SNDMORE标志并尝试发送一个全新的请求,而不是附加到第一个请求(从而打破了REQ套接字的严格发送/接收顺序)。。。因此,套接字的“当前状态”不允许它发送消息的第二部分。尝试使用
send\u multipart()
,或验证参数是否正确传入。

第一点:通常不建议在zmq中使用REQ/REP。使用更通用的经销商/路由器组合。唯一的区别是:

  • 当路由器接收时,路由ID是消息的第一部分。这用于将回复路由回发件人
  • 未强制执行锁步骤req/rep/req/rep序列(这是您看到的错误)
  • 以下是使用经销商的代理版本:

    import zmq
    
    if __name__ == '__main__':
    
        context = zmq.Context()
        socket = context.socket(zmq.STREAM)
        socket.bind("tcp://*:8888")
    
        socket_req = context.socket(zmq.DEALER)
        socket_req.connect("tcp://localhost:5556")
    
        while True:
            clientid, message = socket.recv_multipart()
    
            print("id: %r" % clientid)
            print("request: %s" % message.decode('utf8'))
    
            socket_req.send(message)
    
            reply = socket_req.recv()
            print("reply: %s" % reply.decode('utf8'))
    
            socket.send_multipart([clientid, reply])
    
    和您的服务器,使用路由器:

    import zmq
    import time
    import sys
    
    
    if __name__ == '__main__':
    
        port = 5556
        if len(sys.argv) > 1:
            port = int(sys.argv[1])
    
        context = zmq.Context()
        socket = context.socket(zmq.ROUTER)
        socket.bind("tcp://127.0.0.1:%i" % port)
    
        while True:
            message = socket.recv_multipart()
            req_id = message[0]
            print("Received request: %s" % message[1:])
            time.sleep(1)
            socket.send_multipart([req_id, "world from %s" % port])
    

    我刚刚尝试了send_multipart(),我在REP服务器上遇到了相同的错误。使用ZMQ的SOCK_流来获取消息,我们在消息中获得了一个ID,我应该用该ID将消息发送到REQ服务器吗?这就是您在
    clientid
    变量中得到的结果?我记得关于路由器套接字的一些讨论,这些讨论是关于在代理中维护该ID,然后将其连接回原始客户机进行通信(我认为应该在zmq指南第5章或更高版本中)。所以,试试看。
    import zmq
    import time
    import sys
    
    
    if __name__ == '__main__':
    
        port = 5556
        if len(sys.argv) > 1:
            port = int(sys.argv[1])
    
        context = zmq.Context()
        socket = context.socket(zmq.ROUTER)
        socket.bind("tcp://127.0.0.1:%i" % port)
    
        while True:
            message = socket.recv_multipart()
            req_id = message[0]
            print("Received request: %s" % message[1:])
            time.sleep(1)
            socket.send_multipart([req_id, "world from %s" % port])