Вопрос-Ответ

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

Как управлять исходным IP-адресом пакета ZeroMQ на компьютере с несколькими IP-адресами?

Метод socket.create_connection() стандартной библиотеки Python имеет параметр адреса источника, позволяющий управлять тем, какой исходный IP-адрес использует соединение.

Как мне сделать то же самое с сокетом Python ZeroMQ, учитывая компьютер с несколькими адресами?

В этом случае я использовал iproute2 в Linux ip addr add для создания адресов и архетипов сокетов ZeroMQ PUB/SUB.

Переведено автоматически
Ответ 1

Ну, ZeroMQ немного сложно читать как socket"контрагент" (это не так)

Почему?

Classic socket - это бесплатный ресурс.

ZeroMQ - это довольно сложная иерархия идей и принципов поведения (better - distributed behaviours ), которые помогают проектировать интеллектуальные распределенные вычислительные системы, не затрагивая низкоуровневых (ZeroMQ хорошо абстрагируется ) деталей, которые управляют фактическим потоком событий в штормах суровых условий, с которыми могут столкнуться все распределенные вычислительные системы ( и должны соответственно обрабатываться на низком уровне, если "обещанные" ZeroMQ высокоуровневые абстракции должны быть выполнены и упростить работу с ними). дизайнеры предпочитают сосредоточиться на своей основной прикладной части, а не переделывать колеса (со всеми пробами и ошибками ), дергая за ниточки операционных ресурсов и встряхивая системные сервисы для сбора всего нескольких низко висящих видов фруктов ).


По этим причинам лучше сразу забыть, что ZeroMQ должен быть "чем-то вродеsocket"


Иерархия ZeroMQ менее чем за пять секунд

1:
ZeroMQ обещает простое повторное использование нескольких тривиальных масштабируемых формальных шаблонов связи архетипов, предлагающих определенное распределенное поведение { PUB/SUB | PUSH/PULL | PAIR/PAIR | XPUB/XSUB | ... | REQ/REP }.

2:
За исключением случая использования исключительно транспортного класса без устройств inproc://, во всех остальных случаях ZeroMQ требуется один или несколько экземпляров настраиваемого "движка" - a Context( nIOthreads = N ), N >= 1.

3:
Имея это, можно создать экземпляр любой точки доступа (будущего сокета ), несущей поведенческий архетип с самого момента рождения:

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

4:
Имея экземпляр "точки доступа", готовый "внутри" локального "движка", можно зафиксировать его материализацию во внешней реальности, используя один или несколько (да, больше ... ВАУ! Имеется в виду большее количество входящих обращений в единую точку доступа ("поведенческий узел"), вызывающих любой из этих методов.:

.bind( <transport-class>://<a-class-specific-address> )
или

.connect( <transport-class>://<a-class-specific-address> )

5:
Тогда и только тогда, когда .bind()точка доступа A, готовая к RTO, "посещается" первой действующей .connect() точкой доступа B, готовой к RTO, с любым соответствующим поведением, архетип обмена сообщениями / сигнализации ZeroMQ становится активным (название его также сокетом, вероятно, использовалось по историческим причинам, чтобы упростить объяснение во времени )

( PUB/PUB по очевидным причинам никогда не подойдет, тогда как PUB/SUB и многие другие пары архетипов поведения будут прекрасно совпадать и образуют взаимно "совместимые" модели поведения, которые в конечном итоге заработают и останутся такими )


Итак,
как мне сделать то же самое с сокетом Python ZeroMQ,
учитывая компьютер с несколькими адресами?

Просто используйте полную спецификацию в вызове

.bind( "{ tcp | pgm | epgm }://<ip>:<port#>" ) метод, и все готово.

Это просто.

Круто, не правда ли?

Множество дополнительных приятных сюрпризов скрывается за настройкой производительности, сокращением задержек и настройкой безопасности.

Ответ 2

При попытке .connect() подключиться к удаленному устройству я нашел ответ в документации по протоколу, поставьте исходный ip-адрес перед точкой с запятой в строке подключения:

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

В Python это выглядит следующим образом:

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