2014-10-07 2 views
0

Я не уверен, что я делаю это правильно, но я хотел бы иметь возможность отправлять сообщения на мой сервер под управлением ZMQ из обычных TCP-соединений. На сервере выполняется Python ZMQ на порту 5555 с использованием TCP transport. Я хотел бы иметь возможность отправлять ему сообщения с использованием разных клиентов (Python, Java, PHP), которые используют обычный TCP. Это то, что я до сих пор:Отправлять сообщения на сервер ZeroMQ с использованием обычного TCP, возможно?

SERVER

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

Благодарим за помощь.

ответ

4

ZeroMQ - это протокол, который находится поверх TCP (ну, технически, ZMTP - это протокол; 0MQ - это библиотека, которая реализует протокол ZMTP, а ZeroMQ - это реализация Python 0MQ ...). Вся сигнализация, которую он делает, и все кадрирование (разделение потока байтов на отдельные сообщения) выполняется путем отправки байтов через сокет. Клиент, который не знает, как выполнять сигнализацию и обрамление ZeroMQ, просто увидит кучу мусора.

То, что вы пытаетесь сделать, точно так же, как попытка написать веб-клиент, который просто считывает сокет, ничего не зная о HTTP. Вы получите кучу фреймов, которые вы не знаете, что делать. Единственное различие заключается в том, что в случае HTTP кадрирование иногда (но не всегда) - вы можете иметь MIME-конверты, gzip-транспортное кодирование, chunked transport, ...) просто кучу человекочитаемых ASCII, которые поступают перед данными, в то время как с ZMTP это никогда читаемый человеком ...

Если вы хотите отправить данные через обычный сокет TCP, вы должны сделать это, создав простой TCP сокет на стороне сервера и вызова его send (или sendall, и т. д.). Если вы хотите отправлять данные по каналу ZMTP, вы должны сделать это, проанализировав ZMTP или используя библиотеку, которая делает это для вас (например, ZeroMQ), на стороне клиента.

Еще одна вещь, о которой следует помнить, заключается в том, что, в отличие от ZMTP, TCP не является протоколом, ориентированным на сообщения; все TCP-отправления представляют собой поток байтов. С принимающей стороны нет способа узнать, когда одна отправка заканчивается, а следующая начинается. Таким образом, для почти всего, кроме протокола «отправить запрос, получить ответ, повесить трубку», вам нужно написать свой собственный кадринг. Это может быть так же просто, как «сообщения - это строки, в которых нет новых строк, и каждое сообщение разделяется новой строкой» (в этом случае вы можете просто использовать socket.makefile), но часто формат сообщения должен быть более сложным, или вы должны отправлять «команды», а не просто данные и т. д.

С tdelaney's ответ был удален (что, я думаю, означает, что он невидим для кого-либо под 10K rep), и у меня было полезное предложение, я повторю его здесь, с кредитом должным образом: вы можете (используя библиотеку ZeroMQ) напишите часть промежуточного программного обеспечения, которое говорит ZMTP на сервере, но ваш собственный простой протокол TCP для клиентов. ZeroMQ был специально разработан, чтобы сделать это достаточно легко; как сказал tdelaney, это «похоже на Lego, вы строите надежную коммуникационную инфраструктуру, создавая разные коммуникационные части. Не все части должны быть zeromq».

+0

Спасибо! Именно это и было моим вопросом. Я рассмотрю использование простого TCP с обеих сторон. – Sthe

Смежные вопросы