#include <boost/asio/buffer.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/udp.hpp>
#include <cstdlib>
#include <functional>
#include <iostream>
using boost::asio::ip::udp;
using std::placeholders::_1;
using std::placeholders::_2;
class client
{
public:
client(const udp::endpoint& listen_endpoint)
: socket_(io_context_, listen_endpoint)
{
}
std::size_t receive(const boost::asio::mutable_buffer& buffer,
std::chrono::steady_clock::duration timeout,
boost::system::error_code& error)
{
std::size_t length = 0;
socket_.async_receive(boost::asio::buffer(buffer),
std::bind(&client::handle_receive, _1, _2, &error, &length));
run(timeout);
return length;
}
private:
void run(std::chrono::steady_clock::duration timeout)
{
io_context_.restart();
io_context_.run_for(timeout);
if (!io_context_.stopped())
{
socket_.cancel();
io_context_.run();
}
}
static void handle_receive(
const boost::system::error_code& error, std::size_t length,
boost::system::error_code* out_error, std::size_t* out_length)
{
*out_error = error;
*out_length = length;
}
private:
boost::asio::io_context io_context_;
udp::socket socket_;
};
int main(int argc, char* argv[])
{
try
{
using namespace std;
if (argc != 3)
{
std::cerr << "Usage: blocking_udp_client <listen_addr> <listen_port>\n";
return 1;
}
udp::endpoint listen_endpoint(
boost::asio::ip::make_address(argv[1]),
std::atoi(argv[2]));
client c(listen_endpoint);
for (;;)
{
char data[1024];
boost::system::error_code error;
std::size_t n = c.receive(boost::asio::buffer(data),
std::chrono::seconds(10), error);
if (error)
{
std::cout << "Receive error: " << error.message() << "\n";
}
else
{
std::cout << "Received: ";
std::cout.write(data, n);
std::cout << "\n";
}
}
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}