libzmq
libzmq copied to clipboard
Behaviour of binding a second (UDP)socket on the same endpoint
Issue description
What should happen if I bind a second (udp) socket to the same endpoint?
Environment
Currently testing Linux and OSX. I'm using an external process to send some udp data:
oscsend localhost 1234 /sample/address iTfs 1 3.14 hello
- libzmq version : a01d259db372bff5e049aa966da4efce7259af67
- OS: Linux Debian testing and OSX 10.15
Minimal test code / Steps to reproduce the issue
#include "zmq.h"
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
int main (void)
{
void *context = zmq_ctx_new ();
void *data_socket = zmq_socket (context, ZMQ_DGRAM);
int rc = zmq_bind(data_socket, "udp://*:1234");
if (rc == -1) {
printf ("E: bind failed: %s\n", strerror (errno));
return 1;
}
assert (rc == 0);
// proof we are receiving data
int count = 0;
printf("starting recv\n");
while (count < 10) {
char buffer [100];
rc = zmq_recv (data_socket, buffer, 100, 0);
assert(rc > 0);
printf ("Received Hello %.*s\n", 100, buffer);
count++;
}
// bind another socket on the same port
void *data_socket2 = zmq_socket (context, ZMQ_DGRAM);
rc = zmq_bind(data_socket2, "udp://*:1234");
if (rc == -1) {
printf ("E: bind failed: %s\n", strerror (errno));
return 1;
}
assert (rc == 0);
count = 0;
printf("starting recv\n");
void *poller = zmq_poller_new ();
zmq_poller_add (poller, data_socket, NULL, ZMQ_POLLIN);
zmq_poller_add (poller, data_socket2, NULL, ZMQ_POLLIN);
zmq_poller_event_t events [2];
while (count<10)
{
int rc = zmq_poller_wait_all (poller, events, 2, -1);
assert (rc >= 0);
for (int i = 0; i < 2; ++i) {
if (events[i].socket == data_socket && events[i].events & ZMQ_POLLIN)
{
char buffer [100];
rc = zmq_recv (events[i].socket, buffer, 100, 0);
assert(rc > 0);
printf ("Received data_socket %.*s\n", 100, buffer);
count++;
}
else if (events[i].socket == data_socket2 && events[i].events & ZMQ_POLLIN)
{
char buffer [100];
rc = zmq_recv (events[i].socket, buffer, 100, 0);
assert(rc > 0);
printf ("Received data_socket2 %.*s\n", 100, buffer);
count++;
}
}
}
return 0;
}
What's the actual result?
Linux
...
Received data_socket2 127.0.0.1:52448
Received data_socket2 /sample/address
On OSX no data is received after binding the second socket.
What's the expected result?
Not sure what the behaviour should be but I guess the linux behaviour is right or both sockets should receive the data.
#include "zmq.h"
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
int main (void)
{
// Create a context for the first socket
void *context = zmq_ctx_new ();
void *data_socket = zmq_socket (context, ZMQ_DGRAM);
int rc = zmq_bind(data_socket, "udp://*:1234");
if (rc == -1) {
printf ("E: bind failed: %s\n", strerror (errno));
return 1;
}
assert (rc == 0);
// Proof we are receiving data
int count = 0;
printf("Starting recv on data_socket\n");
while (count < 10) {
char buffer [100];
rc = zmq_recv (data_socket, buffer, 100, 0);
assert(rc > 0);
printf ("Received data_socket: %.*s\n", 100, buffer);
count++;
}
// Create a separate context for the second socket
void *context2 = zmq_ctx_new ();
void *data_socket2 = zmq_socket (context2, ZMQ_DGRAM);
rc = zmq_bind(data_socket2, "udp://*:1234");
if (rc == -1) {
printf ("E: bind failed: %s\n", strerror (errno));
return 1;
}
assert (rc == 0);
count = 0;
printf("Starting recv on data_socket2\n");
void *poller = zmq_poller_new ();
zmq_poller_add (poller, data_socket, NULL, ZMQ_POLLIN);
zmq_poller_add (poller, data_socket2, NULL, ZMQ_POLLIN);
zmq_poller_event_t events [2];
while (count < 10)
{
int rc = zmq_poller_wait_all (poller, events, 2, -1);
assert (rc >= 0);
for (int i = 0; i < 2; ++i) {
if (events[i].socket == data_socket && events[i].events & ZMQ_POLLIN)
{
char buffer [100];
rc = zmq_recv (events[i].socket, buffer, 100, 0);
assert(rc > 0);
printf ("Received data_socket: %.*s\n", 100, buffer);
count++;
}
else if (events[i].socket == data_socket2 && events[i].events & ZMQ_POLLIN)
{
char buffer [100];
rc = zmq_recv (events[i].socket, buffer, 100, 0);
assert(rc > 0);
printf ("Received data_socket2: %.*s\n", 100, buffer);
count++;
}
}
}
// Close the contexts and sockets
zmq_close(data_socket);
zmq_close(data_socket2);
zmq_ctx_destroy(context);
zmq_ctx_destroy(context2);
return 0;
}
Are you saying this does work?