65 votes

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 *:

 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 soulève cette erreur:

ZMQError: pas de tel périphérique

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

Est-ce que cela ne fonctionne que sur IPC sur la même machine?

162voto

aculich Points 4563

Comme @fdb souligne:

Le problème est à la ligne:

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

essayez de changer:

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

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

La documentation pour zmq_bind explique (en gras c'est moi qui souligne):

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

Depuis votre exemple utilise tcp comme protocole de transport nous regardons dans la zmq_tcp de la documentation pour découvrir (encore une fois, c'est moi qui souligne en gras):

Lors de l'affectation d'une adresse à une prise secteur à l'aide de zmq_bind() avec le tcp transport, le point de terminaison ne doit être interprétée comme une interface suivie d'une virgule et du numéro de port TCP à utiliser.

Une interface peut être spécifiée par les éléments suivants:

  • La wild-card *, ce qui signifie que toutes les interfaces disponibles.
  • Le principal adresse IPv4 attribuée à l'interface, dans sa représentation numérique.
  • Le nom de l'interface tel que défini par le système d'exploitation.

Donc, si vous n'êtes pas à l'aide de wild-card ou le nom de l'interface, cela signifie que vous devez utiliser une adresse IPv4 sous forme numérique (pas un nom DNS).

Remarque, cela s'applique uniquement à l'utilisation de l' zmq_bind! D'autre part, il est parfaitement acceptable d'utiliser un nom DNS avec zmq_connect comme discuté plus tard dans les docs pour zmq_tcp:

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

Un de ses pairs, à l'adresse peut être spécifiée par les éléments suivants:

  • Le nom DNS de l'hôte.
  • L'adresse IPv4 par les pairs, dans sa représentation numérique.

43voto

fdb Points 719

Le problème est en ligne:

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

essayez de changer pour:

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

5voto

DNA Points 16180

Mais voyez aussi cette question où bind to tcp://*:5000 fonctionnerait:

Impossible d'obtenir des liaisons python ZeroMQ pour recevoir des messages via IPC.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X