asio async_receive how to get sender ip address

511 views Asked by At

I wrote a small protocol stack to connect to KNX/IP routers. The mechanism is as follows:

  • Discovery_Channel: For discovery the client sends out an UDP/IP packet to multicast address 224.0.23.12. KNX/IP routers listen to this multicast address and reply. The KNX/IP router can potentially be connected to multiple KNX media, so the answer contains a list of services with IP addresses and port, the client can connect to.
  • Communication_Channel: The discovered services from all KNX/IP routers are presented to the user to select which service a connection should be made to.

The problem is that the answer from the KNX/IP routers sometimes doesn't contain a valid IP address, but just 0.0.0.0. In this case I need to take the IP address from where the packet came from. But how can I get this with (non-boost version of) asio?

My code looks like this:

/** client socket */
asio::ip::udp::socket m_socket;

/** search request */
void search_request(
    const IP_Host_Protocol_Address_Information & remote_discovery_endpoint = IP_Host_Protocol_Address_Information({224, 0, 23, 12}, Port_Number),
    const std::chrono::seconds search_timeout = SEARCH_TIMEOUT);

/** search response initiator */
void Discovery_Channel::async_receive_response() {
    /* prepare a buffer */
    m_response_data.resize(256);

    /* async receive */
    m_socket.async_receive(
        asio::buffer(m_response_data),
        std::bind(&Discovery_Channel::response_received, this, std::placeholders::_1, std::placeholders::_2));
}

/** response received handler */
void Discovery_Channel::response_received(const std::error_code & error, std::size_t bytes_transferred) {
    // here the answer provided in m_response_data gets interpreted.
    // @todo how to get the IP address of the sender?

    /* start initiators */
    async_receive_response();
}

So how can I retrieve the IP address of the sender in the Discovery_Channel::response_received method? I basically only have the packet data in m_response_data available.

1

There are 1 answers

6
sehe On BEST ANSWER

On datagram sockets you can (should, likely) use async_receive_from.

It takes a reference to an endpoint variable that will be set to the remote endpoint on success.