このコードはうまく機能します:
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でのみ動作しますか?
問題は次のとおりです。
subscriber.bind("tcp://localhost:5555")
に変更してみてください:
subscriber.bind("tcp://127.0.0.1:5555")
@fdbが指摘するように:
問題は次のとおりです。
subscriber.bind("tcp://localhost:5555")
に変更してみてください:
subscriber.bind("tcp://127.0.0.1:5555")
ただし、これは、理由を理解するためにより多くの説明に値します。
zmq_bind のドキュメントで説明されています(太字の強調):
endpoint引数は、次の2つの部分で構成される文字列です:
transport://address
。 transport部分は、使用する基礎となるトランスポートプロトコルを指定します。 address部分の意味は、選択された基礎となるトランスポートプロトコルに固有です。
この例ではトランスポートプロトコルとしてtcpを使用しているため、 zmq_tcp のドキュメントを参照して発見します(もう一度、太字の強調)。
tcpトランスポートでzmq_bind()を使用してソケットにローカルアドレスを割り当てる場合、endpointはinterfaceとそれに続くコロンとして解釈されます。およびTCP使用するポート番号。
インターフェイスは、次のいずれかで指定できます。
- ワイルドカード*。使用可能なすべてのインターフェースを意味します。
- インターフェイスに割り当てられたプライマリIPv4アドレスの数値表現。
- オペレーティングシステムで定義されているインターフェイス名。
したがって、ワイルドカードまたはインターフェイス名を使用していない場合は、数値形式のIPv4アドレス(DNS名ではない)を使用する必要があることを意味します。
これは、zmq_bind
!の使用にのみ適用されることに注意してください。一方、 zmq_tcp のドキュメントで後述するように、zmq_connect
でDNS名を使用することはまったく問題ありません。
Tmトランスポートでzmq_connect()を使用してソケットをピアアドレスに接続する場合、エンドポイントは、コロンと使用するポート番号TCP)が続くピアアドレスとして解釈されます。
ピアアドレスは、次のいずれかで指定できます。
- ピアのDNS名。
- 数値表現でのピアのIPv4アドレス。