Pyzmq - 向STREAM套接字发送消息

时间:2017-11-08 17:57:13

标签: python pyzmq

我正在尝试在pyzmq中实现两个STREAM套接字之间连接的简单示例。

sender.py

import zmq

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

socket.connect("tcp://localhost:5556")
socket.send("message")

receiver.py

import zmq

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

message = socket.recv()
print("Received -> [ %s ]" % (message))

输出

Received [ b'\x00k\x8bEg' ]
Received [ b'' ]

我想问一下在STREAM套接字之间发送消息的正确方法是什么。

2 个答案:

答案 0 :(得分:1)

您的 socket.recv() -ed数据与ZeroMQ规范完全匹配,但它们不一定让您满意而且您怀疑为什么会这样做,而不是很好地交付精确的副本发送的消息。

所以,要耐心等待并继续阅读。

ZeroMQ最近添加了STREAM socket-archetype是相当具体的

任何对ZeroMQ信令/消息传递工具有几年经验的人都会告诉您最近(v4.x)添加的STREAM原型并不是ZeroMQ流程对ZeroMQ流程互通需求的最佳选择

为什么呢? ZeroMQ工具拥有的所有宝石都必须是STREAM中的快捷方式,以便允许ZeroMQ套接字访问点变得能够“说话”到相反的套接字端点进程,该进程对ZeroMQ一无所知智能套接字更高级协议。

  

原生模式

     

本机模式用于与TCP对等方通信,并允许在任一方向上进行异步请求和回复。   的 ZMQ_STREAM

     

使用 ZMQ_STREAM 传输时,类型tcp://的套接字用于从非ØMQ对等方发送和接收TCP数据。 ZMQ_STREAM套接字可以充当客户端和/或服务器,异步发送和/或接收TCP数据。

     

在接收TCP数据时,ZMQ_STREAM套接字应在将消息部分传递给应用程序之前,将包含发起对等体标识的消息部分添加到消息中。收到的消息在所有连接的对等体中排队等候。

     

发送TCP数据时,ZMQ_STREAM套接字应删除消息的第一部分,并使用它来确定消息应路由到的对等体的身份,并且不可路由的消息应导致{{1} }或EHOSTUNREACH错误。

     

要打开与服务器的连接,请使用 EAGAIN 调用,然后使用zmq_connect() ZMQ_IDENTITY 打电话。

     

要关闭特定连接,请发送标识帧,然后发送零长度消息(参见示例部分)。

     

建立连接后,应用程序将收到零长度消息。同样,当对等体断开连接(或连接丢失)时,应用程序将收到零长度消息。

     

您必须发送一个标识帧,然后发送一个数据帧。身份帧需要zmq_getsockopt()标志,但在数据帧上会被忽略。

     

实施例

ZMQ_SNDMORE

如果您按照多连接套接字案例上的void *ctx = zmq_ctx_new (); assert ( ctx ); /* Create ZMQ_STREAM socket */ void *socket = zmq_socket ( ctx, ZMQ_STREAM ); assert ( socket ); int rc = zmq_bind ( socket, "tcp://*:8080" ); assert ( rc == 0 ); /* Data structure to hold the ZMQ_STREAM ID */ uint8_t id [256]; size_t id_size = 256; /* Data structure to hold the ZMQ_STREAM received data */ uint8_t raw [256]; size_t raw_size = 256; while ( 1 ) { /* Get HTTP request; ID frame and then request */ id_size = zmq_recv ( socket, id, 256, 0 ); assert ( id_size > 0 ); do { raw_size = zmq_recv ( socket, raw, 256, 0 ); assert ( raw_size >= 0 ); } while ( raw_size == 256 ); /* Prepares the response */ char http_response [] = "HTTP/1.0 200 OK\r\n" "Content-Type: text/plain\r\n" "\r\n" "Hello, World!"; /* Sends the ID frame followed by the response */ zmq_send ( socket, id, id_size, ZMQ_SNDMORE ); zmq_send ( socket, http_response, strlen ( http_response ), 0 ); /* Closes the connection by sending the ID frame followed by a zero response */ zmq_send ( socket, id, id_size, ZMQ_SNDMORE ); zmq_send ( socket, 0, 0, 0 ); } zmq_close ( socket ); zmq_ctx_destroy ( ctx ); 行为的描述,发件人方将碰巧在 STREAM <上接收公平队列循环读取/ strong>实例,它连接(1x通过socket + Nx通过.connect().bind())到多个端点,到目前为止无法控制计数或/和性质通信对等体,但在N = < 0, +INF ) - s上有一个公平排队的循环机制。绝对不是一个安全的设计实践。

socket.recv()

答案 1 :(得分:0)

这是在pyzmq中使用单向连接的简化示例。

sender.py

import zmq

context = zmq.Context()
socket = context.socket(zmq.STREAM)

socket.connect("tcp://localhost:5555")
id = socket.getsockopt(zmq.IDENTITY)
socket.send(id, zmq.SNDMORE)
socket.send(b"message")

receiver.py

import zmq

context = zmq.Context()
socket = context.socket(zmq.STREAM)

socket.bind("tcp://*:5555")
id = socket.recv()
socket.recv()    # empty data here
id = socket.recv()
message = socket.recv()
print("received:" + str(message))