I am able communicate UDP packets between a Client and Server running on localhost basically using the below code.
#include <boost/asio.hpp>
#include <boost/array.hpp>
#include <boost/bind.hpp>
#include <thread>
#include <iostream>
#define IPADDRESS "127.0.0.1"
#define UDP_PORT 13251
using boost::asio::ip::udp;
using boost::asio::ip::address;
void Sender(std::string in) {
boost::asio::io_service io_service;
udp::socket socket(io_service);
udp::endpoint remote_endpoint = udp::endpoint(address::from_string(IPADDRESS), UDP_PORT);
socket.open(udp::v4());
boost::system::error_code err;
auto sent = socket.send_to(boost::asio::buffer(in), remote_endpoint, 0, err);
socket.close();
std::cout << "Sent bytes" << sent << "\n";
}
struct Client {
boost::asio::io_service io_service;
udp::socket socket{io_service};
boost::array<char, 1024> recv_buffer;
udp::endpoint remote_endpoint;
int count = 3;
void handle_receive(const boost::system::error_code& error, size_t bytes_transferred) {
if (error) {
std::cout << "Receive failed: " << error.message() << "\n";
return;
}
std::cout << "Received: '" << std::string(recv_buffer.begin(), recv_buffer.begin()+bytes_transferred) << "' (" << error.message() << ")\n";
if (--count > 0) {
std::cout << "Count: " << count << "\n";
wait();
}
}
void wait() {
socket.async_receive_from(boost::asio::buffer(recv_buffer),
remote_endpoint,
boost::bind(&Client::handle_receive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
void Receiver()
{
socket.open(udp::v4());
socket.bind(udp::endpoint(address::from_string(IPADDRESS), UDP_PORT));
wait();
std::cout << "Receiving\n";
io_service.run();
std::cout << "Receiver exit\n";
}
};
int main(int argc, char *argv[])
{
Client client;
std::thread r([&] { client.Receiver(); });
std::string input = argc>1? argv[1] : "hello world";
std::cout << "Input is '" << input.c_str() << "'\nSending it to Sender Function...\n";
for (int i = 0; i < 3; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
Sender(input);
}
r.join();
}
This works great if the client and server both are running on localhost that is 127.0.0.1. But, it does not work if client and server are running on different devices. I believe that the issue is in the configuring of udp::endpoint
on both sides.
The server is running on a machine which is a router by itself. The client device connects to it and thus it is P2P where only one client and one server is involved. The local inet address of the server device is 192.168.1.1
. Next, the Client connects to the Server and gets assigned with the IP 192.168.1.20
.
For the UDP communication, I to assigned server side udp::endpoint
to 192.168.1.1
and client side udp::endpoint
to 192.168.1.20
. But I still don't get UDP packets. What am I missing?
If I give the endpoint set up logic in a method then this is how it is:
boost::asio::ip::udp::endpoint remote_endpoint;
boost::asio::io_service io_service;
udp::socket udp_socket{io_service};
void PrepareUDPEndpoints(bool on_server_side) {
std::string address;
if (on_server_side) {
address = "192.168.1.1";
remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string(address), 13251);
udp_socket.open(boost::asio::ip::udp::v4());
} else {
address = "192.168.1.20";
udp_socket.open(boost::asio::ip::udp::v4());
remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string(address), 13251);
udp_socket.bind(remote_endpoint);
}
}
I am getting the UDP packets "absolutely okay on localhost 127.0.0.1
" but no packets at all when client and server running on 2 different machines. What am I doing wrong?