web-dev-qa-db-ja.com

zeromqがlocalhostで動作しないのはなぜですか?

このコードはうまく機能します:

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がlocalhostインターフェイスを使用できないのはなぜですか?

同じマシンでIPCでのみ動作しますか?

62
user756428

問題は次のとおりです。

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

に変更してみてください:

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

@fdbが指摘するように:

問題は次のとおりです。

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

に変更してみてください:

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

ただし、これは、理由を理解するためにより多くの説明に値します。

zmq_bind のドキュメントで説明されています(太字の強調):

endpoint引数は、次の2つの部分で構成される文字列です:transport://addresstransport部分は、使用する基礎となるトランスポートプロトコルを指定します。 address部分の意味は、選択された基礎となるトランスポートプロトコルに固有です。

この例ではトランスポートプロトコルとしてtcpを使用しているため、 zmq_tcp のドキュメントを参照して発見します(もう一度、太字の強調)。

tcpトランスポートでzmq_bind()を使用してソケットにローカルアドレスを割り当てる場合、endpointinterfaceとそれに続くコロンとして解釈されます。およびTCP使用するポート番号。

インターフェイスは、次のいずれかで指定できます。

  • ワイルドカード*。使用可能なすべてのインターフェースを意味します。
  • インターフェイスに割り当てられたプライマリIPv4アドレスの数値表現
  • オペレーティングシステムで定義されているインターフェイス名。

したがって、ワイルドカードまたはインターフェイス名を使用していない場合は、数値形式のIPv4アドレス(DNS名ではない)を使用する必要があることを意味します。

これは、zmq_bind!の使用にのみ適用されることに注意してください。一方、 zmq_tcp のドキュメントで後述するように、zmq_connectでDNS名を使用することはまったく問題ありません。

Tmトランスポートでzmq_connect()を使用してソケットをピアアドレスに接続する場合、エンドポイントは、コロンと使用するポート番号TCP)が続くピアアドレスとして解釈されます。

ピアアドレスは、次のいずれかで指定できます。

  • ピアのDNS名。
  • 数値表現でのピアのIPv4アドレス。
154
aculich