title: Boost::asio UDP Broadcast with ephemeral port
body: <p>I'm having trouble with udp broadcast transactions under boost::asio, related to the following code snippet. Since I'm trying to broadcast in this instance, so deviceIP = "255.255.255.255". devicePort is a specified management port for my device. I want to use an ephemeral local port, so I would prefer if at all possible not to have to socket.bind() after the connection, and the code supports this for unicast by setting localPort = 0.</p>
  
  <pre><code>boost::asio::ip::address_v4 targetIP = boost::asio::ip::address_v4::from_string(deviceIP);
  m_targetEndPoint = boost::asio::ip::udp::endpoint(targetIP, devicePort);
  
  m_ioServicePtr = boost::shared_ptr&lt;boost::asio::io_service&gt;(new boost::asio::io_service);
  m_socketPtr = boost::shared_ptr&lt;boost::asio::ip::udp::socket&gt;(new boost::asio::ip::udp::socket(*m_ioServicePtr));
  m_socketPtr-&gt;open(m_targetEndPoint.protocol());
  
  m_socketPtr-&gt;set_option(boost::asio::socket_base::broadcast(true));
  
  // If no local port is specified, default parameter is 0
  // If local port is specified, bind to that port.
  if(localPort != 0)
  {
    boost::asio::ip::udp::endpoint localEndpoint(boost::asio::ip::address_v4::any(), localPort);
    m_socketPtr-&gt;bind(localEndpoint);
  }
  
  if(m_forceConnect)
    m_socketPtr-&gt;connect(m_targetEndPoint);
  
  this-&gt;AsyncReceive(); // Register Asynch Recieve callback and buffer
  m_socketThread = boost::shared_ptr&lt;boost::thread&gt;(new boost::thread(boost::bind(&amp;MyNetworkBase::RunSocketThread, this))); // Start thread running io_service process
  </code></pre>
  
  <p>No matter what I do in terms of the following settings, the transmit is working fine, and I can use Wireshark to see the response packets coming back from the device as expected. These response packets are also broadcasts, as the device may be on a different subnet to the pc searching for it.</p>
  
  <p>The issues are extremely strange to my mind, but are as follows:</p>
  
  <ol>
  <li>If I specify the local port and set m_forceConnect=false, everything works fine, and my recieve callback fires appropriately.</li>
  <li>If I set m_forceConnect = true in the constructor, but pass in a local port of 0, the transmit works fine, but my receive callback never fires. I would assume this is because the 'target' (m_targetEndpoint) is 255.255.255.255, and since the device has a real IP, the response packet gets filtered out.</li>
  <li>(<em>what I actually want</em>) If m_forceConnect = false (and data is transmitted using a send_to call), and local port = 0, therefore taking an ephemeral port, my RX callback immediately fires with an error code 10022, which I believe is an "Invalid Argument" socket error.</li>
  </ol>
  
  <p>Can anyone suggest why I can't use the connection in this manner (not explicitly bound and not explicitly connected)? I obviously don't want to use socket.connect() in this case, as I want to respond to anything I receive. I also don't want to use a predefined port, as I want the user to be able to construct multiple copies of this object without port conflicts.</p>
  
  <p>As some people may have noticed, the overall aim of this is to use the same network-interface base-class to handle both the unicast and broadcast cases. Obviously for the unicast version, I can perfectly happily m_socket->connect() as I know the device's IP, and I receive the responses since they're from the connected IP address, therefore I set m_forceConnect = true, and it all just works.</p>
  
  <p>As all my transmits use send_to, I have also tried to socket.connect(endpoint(ip::addressv4::any(), devicePort), but I get a 'The requested address is not valid in its context' exception when I try it.</p>
  
  <p>I've tried a pretty serious hack:</p>
  
  <pre><code>boost::asio::ip::udp::endpoint localEndpoint(boost::asio::ip::address_v4::any(), m_socketPtr-&gt;local_endpoint().port());
  m_socketPtr-&gt;bind(localEndpoint);
  </code></pre>
  
  <p>where I extract the initial ephemeral port number and attempt to bind to it, but funnily enough that throws an Invalid Argument exception when I try and bind.</p>