Ответ 1
Проблема находится в строке:
subscriber.bind("tcp://localhost:5555")
попытайтесь изменить на:
subscriber.bind("tcp://127.0.0.1:5555")
Этот код отлично работает:
import zmq, json, time
def main():
context = zmq.Context()
subscriber = context.socket(zmq.SUB)
subscriber.bind("ipc://test")
subscriber.setsockopt(zmq.SUBSCRIBE, '')
while True:
print subscriber.recv()
def main():
context = zmq.Context()
publisher = context.socket(zmq.PUB)
publisher.connect("ipc://test")
while True:
publisher.send( "hello world" )
time.sleep( 1 )
Но этот код не работает:
import zmq, json, time
def recv():
context = zmq.Context()
subscriber = context.socket(zmq.SUB)
subscriber.bind("tcp://localhost:5555")
subscriber.setsockopt(zmq.SUBSCRIBE, '')
while True:
print subscriber.recv()
def send():
context = zmq.Context()
publisher = context.socket(zmq.PUB)
publisher.connect("tcp://localhost:5555")
while True:
publisher.send( "hello world" )
time.sleep( 1 )
Возникает эта ошибка:
ZMQError: Нет такого устройства
Почему zeromq не может использовать локальные интерфейсы?
Работает ли он только на IPC на одном компьютере?
Проблема находится в строке:
subscriber.bind("tcp://localhost:5555")
попытайтесь изменить на:
subscriber.bind("tcp://127.0.0.1:5555")
Как указывает @fdb:
Проблема находится в строке:
subscriber.bind("tcp://localhost:5555")
попытайтесь изменить на:
subscriber.bind("tcp://127.0.0.1:5555")
Однако это заслуживает большего объяснения, чтобы понять, почему.
Документация для zmq_bind объясняет (смелый акцент мой):
Аргумент конечной точки - это строка, состоящая из двух частей:
transport://address
. Транспортная часть указывает основные транспортный протокол для использования. Значение адресной части является специфическим к выбранному транспортному протоколу.
Поскольку ваш пример использует tcp в качестве транспортного протокола, мы смотрим в документации zmq_tcp, чтобы обнаружить (опять же, смелый акцент мой):
При назначении локального адреса сокету с помощью zmq_bind() с tcp, конечная точка должна интерпретироваться как интерфейс за которым следует двоеточие и номер порта TCP.
Интерфейс может быть указан одним из следующих:
- Дикая карта *, означающая все доступные интерфейсы.
- Основной IPv4-адрес, назначенный интерфейсу, в его числовом представлении.
- Имя интерфейса, определяемое операционной системой.
Итак, если вы не используете wild-card или имя интерфейса, значит, вы должны использовать IPv4-адрес в числовой форме (не DNS-имя).
Обратите внимание, что это относится только к использованию zmq_bind
! С другой стороны, отлично использовать DNS-имя с zmq_connect
, как описано ниже в документах для zmq_tcp:
При подключении сокета к одноранговому адресу с помощью zmq_connect() с tcp-транспорт, конечная точка должна интерпретироваться как адрес однорангового узла за которым следует двоеточие и номер порта TCP.
Одноранговый адрес может быть указан одним из следующих способов:
- DNS-имя однорангового узла.
- Адрес IPv4 однорангового узла в его числовом представлении.