2011-05-16 63 views
53

此代碼的偉大工程:爲什麼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: No such device

爲什麼不能zeromq使用localhost接口?

它只在同一臺機器上的IPC上工作嗎?

回答

33

的問題是在行:

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

嘗試改變:

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

我喜歡用像127.0.0.101更高的地址,並改變它每個應用程序。比IPC插座更清潔。 – 2011-07-01 01:39:03

+17

@fdb是的,這解決了問題,但並不能解釋爲什麼!它需要[更多解釋](http://stackoverflow.com/a/8958414/462302)。 – aculich 2012-01-22 02:12:49

126

由於@fdb指出:

的問題是在行:

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

嘗試更改爲:

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

但是這需要更多的解釋來理解爲什麼。

zmq_bind的文檔說明(粗體重點煤礦):

The endpoint argument is a string consisting of two parts as follows: transport://address . The transport part specifies the underlying transport protocol to use. The meaning of the address part is specific to the underlying transport protocol selected.

由於您的示例使用TCP作爲傳輸協議,我們的zmq_tcp文檔中查找發現(再次,大膽重點煤礦):

When assigning a local address to a socket using zmq_bind() with the tcp transport, the endpoint shall be interpreted as an interface followed by a colon and the TCP port number to use.

An interface may be specified by either of the following:

  • The wild-card *, meaning all available interfaces.
  • The primary IPv4 address assigned to the interface, in its numeric representation.
  • The interface name as defined by the operating system.

因此,如果您不使用通配符或接口名稱,那麼這意味着您必須使用數字形式的IPv4地址(而不是DNS名稱)。

注意,這僅適用於使用zmq_bind!在另一方面,這是完全正常使用,因爲在文檔中進行zmq_tcp稍後討論與zmq_connect DNS名稱:

When connecting a socket to a peer address using zmq_connect() with the tcp transport, the endpoint shall be interpreted as a peer address followed by a colon and the TCP port number to use.

A peer address may be specified by either of the following:

  • The DNS name of the peer.
  • The IPv4 address of the peer, in its numeric representation.
+3

這是一個奇怪的實現。 – huggie 2014-12-07 05:58:19

+0

啊一個非正交的API – RichardOD 2017-06-12 15:50:52

相關問題