python - zmq - ¿Por qué no funciona zeromq en localhost?
zmq python example (2)
Este código funciona muy bien:
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 )
Pero este código no * funciona:
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 )
Plantea este error:
ZMQError: No existe tal dispositivo
¿Por qué, no puede zeromq usar interfaces localeshost?
¿Solo funciona en IPC en la misma máquina?
Como señala @fdb:
El problema está en la línea:
subscriber.bind("tcp://localhost:5555")
tratar de cambiar a:
subscriber.bind("tcp://127.0.0.1:5555")
Sin embargo, esto merece más explicación para entender por qué.
La documentación para zmq_bind explica (el énfasis en negrita es mío):
El argumento del punto final es una cadena que consta de dos partes de la siguiente manera:
transport://address
. La parte de transporte especifica el protocolo de transporte subyacente a utilizar. El significado de la parte de la dirección es específico del protocolo de transporte subyacente seleccionado.
Ya que su ejemplo usa TCP como el protocolo de transporte, buscamos en la documentación de zmq_tcp para descubrir (de nuevo, el énfasis en negrita es mío):
Al asignar una dirección local a un socket utilizando zmq_bind () con el transporte tcp , el punto final se interpretará como una interfaz seguida de dos puntos y el número de puerto TCP que se debe usar.
Una interfaz puede ser especificada por cualquiera de los siguientes:
- El comodín *, que significa todas las interfaces disponibles.
- La dirección IPv4 primaria asignada a la interfaz, en su representación numérica .
- El nombre de la interfaz como lo define el sistema operativo.
Por lo tanto, si no está usando el comodín o el nombre de la interfaz, significa que debe usar una dirección IPv4 en forma numérica (no un nombre DNS).
Tenga en cuenta que esto solo se aplica al uso de zmq_bind
! Por otro lado, es perfectamente zmq_connect
usar un nombre de DNS con zmq_connect
como se explica más adelante en los documentos para zmq_tcp :
Cuando se conecta un socket a una dirección de igual usando zmq_connect () con el transporte tcp, el punto final se interpretará como una dirección de igual seguida por dos puntos y el número de puerto TCP que se usará.
La dirección de un compañero puede ser especificada por cualquiera de los siguientes:
- El nombre DNS del par.
- La dirección IPv4 del par, en su representación numérica.
El problema está en la línea:
subscriber.bind("tcp://localhost:5555")
tratar de cambiar a:
subscriber.bind("tcp://127.0.0.1:5555")