3

When I'm working on a UDP server I usually set the socket to listen on specified port and accept any IP. Keep in mind that sync receive works properly here.

std::unique_ptr<boost::asio::ip::udp::socket> socketUDP;    
socketUDP.reset(new udp::socket(io_serviceUDP, udp::endpoint(udp::v4(), 9999)));

However, I would really like to have 2 different server applications listening at the same port (9999) but accepting only a single IP (I already know that IP). Each of the apps has its own client with its own IP. But for some reason the following doesn't work (not receiving any packets in the app, while Wireshark can see it)

socketUDP.reset(new udp::socket(m_io_serviceUDP, udp::endpoint(asio::ip::address::from_string("169.254.1.2"), 9999)));

Please note : 1) According to the answer for : Issue with broadcast using Boost.Asio this should actually work. Of course my understanding isn't quite correct as I'm missing something

2) The provided IP is valid, works, sends data(confirmed by wireshark) and can be pinged

Community
  • 1
  • 1
Arrr
  • 31
  • 1
  • 4
  • do you have it working now? I use the sample for UDP multicast from Boost 1.66 and it works. – CaTx Mar 04 '18 at 05:01

1 Answers1

2

The issue is that your socketUDP's are not configured with:

set_option(boost::asio::ip::udp::socket::reuse_address(true));

However, simply calling the line above on your sockets won't work, because you must call reuse_address before the socket is bound to an endpoint... But you're constructing udp::socket with an endpoint which opens it and binds it to the endpoint, see basic_datagram_socket.

The solution is to call the constructor which just takes an io_service; open it, set the reuse_addressoption and then bind it, e.g.:

// construct the socket
boost::asio::ip::udp::socket  socket_(io_service_);

// open it
boost::asio::ip::udp::endpoint rx_endpoint_(udp::v4(), 9999);
socket_.open(rx_endpoint_.protocol(), error);
if (error)
  return false;

// then set it for reuse and bind it
socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
socket_.bind(rx_endpoint_, error);
if (error)
   return false;

// set multicast group, etc.
socket_.set_option(boost::asio::ip::multicast::join_group(ip_address));
...
kenba
  • 4,303
  • 1
  • 23
  • 40
  • I think that's really great comment but it address an issue that would happen afterwards. Right now even 1 server won't work with a specified IP. – Arrr Sep 26 '16 at 07:32
  • I sorry to hear that @Arrr..There's some code for a `UDP` receiver that works (to the best of my knowledge) [here](https://github.com/kenba/via-httplib/tree/master/include/via/comms). It's only documented for `TCP` sockets, but just replace the `tcp_adaptor` with `udp_adaptor` and call the `receive_multicast` function. BTW, which port are you listening on: `9999` or `4747`? – kenba Sep 26 '16 at 14:27