jeffbass / imagezmq

A set of Python classes that transport OpenCV images from one computer to another using PyZMQ messaging.
MIT License
1.02k stars 161 forks source link

ImageHub with non-default open_port parameter #48

Open kdziedzic66 opened 4 years ago

kdziedzic66 commented 4 years ago

I have two machines: my laptop and remote server. They are in the same network ( my laptop is connected via VPN ) and I want to set ImageHub to recive images only from my laptop, so I set open_port parameter to tcp://my_laptop_ip:5555 and it doesnt work for me. When i set open_port to default ( recive from all ips ) than it works fine. There are no examples of ImageHub with non-default open_port in the repository neither I have found any in the internet so Im wondering if this is an issue or do I miss something ?

jeffbass commented 4 years ago

Hi @kdziedzic66,

Great question, but this is not an issue; it is an expected ZMQ behavior. There is a difference between “open_port” and “connect_to”. It is subtle and is documented in the ZMQ API docs for tcp here (page title is "zmq_tcp(7)”).

The open_port= specifies the port to bind to; it must be either “*” or the numeric address of the “primary IPv4 or IPv6 address assigned to the interface” per the docs above. This means the only numeric address that is valid for the “open_port=" is the address of the ImageHub itself. It must be it’s own numeric tcp address. Or "*". But NOT the address of any other computer. And NOT a DNS text style address.

Using REQ/REP, I tested between 2 computers. The addresses that worked are:

# in the code for REQ/REP sender (this computer’s address is `192.168.86.38`)
sender = imagezmq.ImageSender(connect_to='tcp://192.168.86.39:5555’)  # this works fine; it is the address of the other computer

# in the code for REQ/REP hub receiver (this computer’s address is 192.168.86.39)
image_hub = imagezmq.ImageHub(open_port='tcp://192.168.86.39:5555’)  # this works fine; it uses the address of THIS computer
image_hub = imagezmq.ImageHub(open_port='tcp://*:5555’)  # this works fine; it is what I use all the time
image_hub = imagezmq.ImageHub(open_port='tcp://192.168.86.38:5555’)  # this address of the other computer DOES NOT WORK
image_hub = imagezmq.ImageHub(open_port='tcp://rpi24:5555’)  # a DNS text name address DOES NOT WORK for “open_port="

The computer that binds a port with “open_port=“ (the HUB in REQ/REP) must specify “*” or its own numeric tcp address; it cannot specific another computer’s address. It cannot specify a DNS name for another computer. It cannot specify a DNS name for itself.

The computer that connects with “connect_to=“ specifies both the address and the port of the computer it is connecting to.

As I said, this is documented in the ZMQ documentation above if you read it very carefully:

Assigning a local address to a socket

When assigning a local address to a socket using _zmqbind() 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 or IPv6 address assigned to the interface, in its numeric representation.

Note the title "Assigning a local address" to a socket. Versus "Connecting a socket" (on another computer):

Connecting a socket

When connecting a socket to a peer address using _zmqconnect() with the tcp transport, the endpoint shall be interpreted as a peer address followed by a colon and the TCP port number to use. You can optionally specify a source_endpoint which will be used as the source address for your connection; tcp://source_endpoint;'endpoint', see the interface description above for details. A peer address may be specified by either of the following:

  • The DNS name of the peer.
  • The IPv4 or IPv6 address of the peer, in its numeric representation.

Hope this helps. Try using your hub computer's own numeric tcp address in the "open_port=". It should work. But it is just as easy to use "*" and it does the same thing. Note that the "*" is not really a "wild card" for lots of tcp addresses. It is just shorthand for "the tcp address of this computer". Since "*" always works and is the default, I don't have a non-default "open_port=" example in the repository. Perhaps I should put the above explanation in the imageZMQ docs, but it is probably way too much detail for most users. Jeff