web-dev-qa-db-fra.com

Pourquoi zeromq ne fonctionne-t-il pas sur localhost?

Ce code fonctionne très 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 )

Mais ce code ne fonctionne pas * fonctionne:

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 )

Il déclenche cette erreur:

ZMQError: aucun périphérique de ce type

Pourquoi, zeromq ne peut-il pas utiliser les interfaces localhost?

Cela fonctionne-t-il uniquement sur IPC sur la même machine?

62
user756428

Le problème est en ligne:

subscriber.bind("tcp://localhost:5555")

essayez de changer pour:

subscriber.bind("tcp://127.0.0.1:5555")
39
fdb

Comme le souligne @fdb:

Le problème est en ligne:

subscriber.bind("tcp://localhost:5555")

essayez de changer pour:

subscriber.bind("tcp://127.0.0.1:5555")

Cependant, cela mérite plus d'explications pour comprendre pourquoi.

La documentation de zmq_bind explique (gras en gras):

L'argument de point de terminaison est une chaîne composée de deux parties, comme suit: transport://address. La partie transport spécifie le protocole de transport sous-jacent à utiliser. La signification de la partie adresse est spécifique au protocole de transport sous-jacent sélectionné.

Puisque votre exemple utilise tcp comme protocole de transport, nous regardons dans la documentation zmq_tcp pour découvrir (encore une fois, le gras est le mien):

Lors de l'attribution d'une adresse locale à un socket à l'aide de zmq_bind () avec le transport tcp , le point de terminaison doit être interprété comme un interface suivie d'un deux-points et du numéro de port TCP à utiliser.

Une interface peut être spécifiée par l'un des éléments suivants:

  • Le caractère générique *, c'est-à-dire toutes les interfaces disponibles.
  • Adresse IPv4 principale attribuée à l'interface, dans sa représentation numérique .
  • Nom d'interface tel que défini par le système d'exploitation.

Donc, si vous n'utilisez pas de caractère générique ou le nom d'interface, cela signifie que vous devez utiliser une adresse IPv4 sous forme numérique (pas un nom DNS).

Remarque, cela ne s'applique qu'à l'utilisation de zmq_bind! En revanche, il est tout à fait correct d'utiliser un nom DNS avec zmq_connect comme expliqué plus loin dans la documentation pour zmq_tcp :

Lors de la connexion d'un socket à une adresse homologue à l'aide de zmq_connect () avec le transport tcp, le point de terminaison doit être interprété comme une adresse homologue suivie par deux points et le numéro de port TCP TCP à utiliser).

Une adresse d'homologue peut être spécifiée par l'un des éléments suivants:

  • Nom DNS de l'homologue.
  • L'adresse IPv4 de l'homologue, dans sa représentation numérique.
154
aculich