可以使用传统的TCP向ZeroMQ服务器发送消息吗?

时间:2014-10-07 23:30:02

标签: python linux sockets tcp zeromq

我不确定我是否正确行事,但我希望能够从正常的TCP连接向运行ZMQ的服务器发送消息。服务器使用5555在端口TCP transport上运行Python ZMQ。我希望能够使用使用传统TCP的不同客户端(Python,Java,PHP)向其发送消息。这就是我到目前为止所做的:

服务器

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

while True:
    message = socket.recv()
    print message
    socket.send('{"name":"someone"}')

客户端

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 5555))
s.send('Hello, World!')
data = s.recv(1024)
print data

在客户端上打印data并未向我提供我期望的消息。我明白了:。我尝试bytes(data).decode('utf8')认为我得到的是一个字节数组,但是我收到以下错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)

我只是想知道:这有可能吗?或者我做错了什么?另外,是推荐吗?

我不在客户端上使用ZMQ的原因是我希望减少依赖项的数量(ZeroMQ为1)。

感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

ZeroMQ是一种位于TCP之上的协议(从技术上讲,ZMTP是一种协议; 0MQ是实现ZMTP协议的库,而ZeroMQ是0MQ的Python实现......)。它所做的所有信令以及所有的成帧(将字节流分成单独的消息)都是通过套接字发送字节来完成的。不知道如何进行ZeroMQ信令和框架的客户端只会看到一堆垃圾。

您尝试做的就像尝试编写一个只读取套接字的Web客户端,而不了解任何有关HTTP的信息。你会得到一堆你不知道该怎么做的框架。唯一的区别是,在HTTP的情况下,框架有时(但不总是 - 你可以有MIME信封,gzip传输编码,分块传输,......)只是在数据之前出现的一堆人类可读的ASCII,使用ZMTP时,永远不会人类可读...

如果要通过普通TCP套接字发送数据,则必须通过在服务器端创建普通TCP套接字并调用其send(或sendall等)方法来实现此目的。 。如果要通过ZMTP通道发送数据,则必须通过解析ZMTP或在客户端使用为您执行此操作的库(如ZeroMQ)来完成此操作。

要记住的另一件事是,与ZMTP不同,TCP不是面向消息的协议;所有TCP发送都是一个字节流。从接收方,无法知道何时发送结束而下一个发送结束。因此,对于除了“发送请求,获得响应,挂断”协议之外的任何内容,您需要编写自己的某种框架。这可以简单到“消息是其中没有换行符的字符串,每条消息由换行符分隔”(在这种情况下,您可以只使用socket.makefile),但通常消息格式必须更多很复杂,或者你必须发送“命令”而不仅仅是数据等。

由于tdelaney's答案已被删除(我认为这意味着它对10K以下的任何人都不可见),并且有一个有用的建议,我会在这里重复一遍,信用到期:你可以(使用ZeroMQ库)写一个中间件,它将ZMTP与服务器对话,但是你自己的简单的基于TCP的协议给客户端。 ZeroMQ经过专门设计,使其变得相当简单;正如tdelaney所说,它“有点像乐高,你通过构建不同的通信部分来建立一个强大的通信基础设施。并非所有部分都需要是zeromq。”