How to control the source IP address of a ZeroMQ packet on a machine with multiple IPs?

The Python standard library’s socket.create_connection()method has a source address option, for controlling which source IP a connection uses.

How do I do the same thing with a Python ZeroMQ socket, given a machine that has multiple addresses?

In this case, I’ve been using Linux’s iproute2 ip addr add to create the addresses and the ZeroMQ PUB/SUB socket-archetypes.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Well, ZeroMQ is a bit tricky to read as a socket-“counterparty” ( it’s not )

Why?

Classical socket is a free-to-harness resource.

ZeroMQ is a rather complex hierarchy of ideas and principles of behaviours ( better – distributed behaviours ), that help design smart distributed computing systems, without touching the low-level ( ZeroMQ well abstracted ) details, that control the actual flow of events in the storms of harsh conditions all distributed computing systems are open to face ( and have to handle at low level accordingly, if the high-level abstractions “promised” by ZeroMQ to keep are to be fulfilled and ease the designers’ minds to focus rather on his/her core application part, not re-designing wheels ( with all trials and errors ) on pulling strings on O/S resources and shaking systems services for collecting just a few low-hanging types of fruits ).


For these reasons better straight forget ZeroMQ to be “something-like-socket


ZeroMQ hierarchy in less than a five seconds

1:
ZeroMQ promises an easy re-use of a few trivial Scalable Formal Communication Pattern archetypes offering a particular distributed behaviour { PUB/SUB | PUSH/PULL | PAIR/PAIR | XPUB/XSUB | ... | REQ/REP }.

2:
Except a case of exclusively using just a device-less inproc:// transport-class, in all other cases, ZeroMQ needs one or more instances of a tunable “engine” – a Context( nIOthreads = N ), N >= 1.

3:
Having this, any ( future socket ) Access Point could get instantiated, bearing a behavioural archetype since the very moment of birth:

aSubscribeCHANNEL = aLocalCONTEXT.socket( zmq.SUB )      # this is NOT a <SOCKET>
#                                 ^^^^^^__________________ even it was typed in

4:
Having an “Access Point” instance ready “inside” the local “engine“, one can lock-in its materialisation in the external-reality, using one or more ( yes, more … WOW! Meaning more incoming pulling-strings into / whistles blowing out from a single Access Point “behaviour-node” ) calls to either of these methods:
.bind( <transport-class>://<a-class-specific-address> )
or
.connect( <transport-class>://<a-class-specific-address> )

5:
If and only if a .bind()-RTO-ready Access Point A “gets visited” by a first live .connect()-RTO-ready Access Point B, having any matching behaviour pairing, the ZeroMQ-messaging/signalling archetype gets live ( naming it also a socket was probably used for historical reasons, to ease an explanation in times )

( PUB/PUB will never fit, for obvious reasons, whereas PUB/SUB and many other behaviour-archetype pairs will and do lovely match and form the mutually-“compatible”-behaviours that will finally go live and stay so )


So,
how do I do the same thing with a Python ZeroMQ socket,
given a machine that has multiple addresses?

Simply use the fully qualified specification in a call to
.bind( "{ tcp | pgm | epgm }://<ip>:<port#>" ) method and you are done.

That easy.

Cool, isn’t it?

Many further pleasant surprises under the hood of performance tuning, latency shaving and security tweaking.

Method 2

When trying to .connect() to a remote, I found the answer in the protocol documentation, put the source ip before a semicolon in the connect string:

rc = zmq_connect(socket, "tcp://192.168.1.17:5555;192.168.1.1:5555")

In Python, this looks like:

socket = zmq.Context().socket(zmq.SUB)
socket.connect('tcp://192.168.1.17:5555;192.168.1.1:5555')


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x