72

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

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でのみ機能しますか?

4

2 に答える 2

184

@fdbが指摘するように:

問題は次のとおりです。

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

次のように変更してみてください。

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

ただし、これは理由を理解するためにさらに説明する価値があります。

zmq_bindのドキュメントでは、次のように説明しています(太字の強調鉱山)。

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

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

tcpトランスポートでzmq_bind()を使用してソケットにローカルアドレスを割り当てる場合 、エンドポイントは、 使用するコロンとTCPポート番号が後に続くインターフェイスとして解釈されます。

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

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

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

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

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

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

  • ピアのDNS名。
  • 数値表現でのピアのIPv4アドレス。
于 2012-01-22T02:11:56.413 に答える
53

問題は次のとおりです。

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

次のように変更してみてください。

subscriber.bind("tcp://127.0.0.1:5555")
于 2011-05-16T22:10:31.157 に答える