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.
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.