Reputation: 1571
I've modified the UDP client code from Boost daytime client tutorial into the following:
class UDPClient
{
public:
udp::socket* socket;
udp::endpoint* receiver_endpoint;
boost::array<char, 1024> recv_buffer;
UDPClient();
void do_receive();
void handle_receive(const boost::system::error_code& error, size_t);
};
UDPClient::UDPClient()
{
boost::asio::io_service io_service;
udp::resolver resolver(io_service);
udp::resolver::query query(udp::v4(), "127.0.0.1", "8888");
receiver_endpoint = new udp::endpoint(*resolver.resolve(query));
socket = new udp::socket(io_service);
socket->open(udp::v4());
do_receive();
while (true)
{
io_service.poll();
Sleep(1);
}
}
void UDPClient::do_receive()
{
socket->async_receive_from(boost::asio::buffer(recv_buffer), *receiver_endpoint,
boost::bind(&UDPClient::handle_receive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void UDPClient::handle_receive(const boost::system::error_code& error, size_t bytes_transferred)
{
cout << "ulala" << endl;
if (!error || error == boost::asio::error::message_size)
do_receive();
}
If all works out according to plan, "ulala" would only be printed if there is an incoming message. However that is not the case here... The handler gets called instantaneously and "ulala" is printed regardless of whether there is an incoming message. I've tried a few different things: swapping io_service.poll() with io_service.run() and io_service.run_one(), as well as removing Sleep(1), but none of those changes have any effect on the problem. What should I do?
Thanks in advance!
Upvotes: 4
Views: 13227
Reputation: 394054
socket = new udp::socket(io_service);
socket->open(udp::v4());
sets up a socket for sending to arbitrary endpoints. To receive ("listen"), use
socket = new udp::socket(io_service, udp::endpoint(udp::v4(), 8888));
Besides that, the socket and receiver_endpoint are leaked now. To fix that:
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/array.hpp>
#include <iostream>
using boost::asio::ip::udp;
class UDPClient
{
public:
boost::asio::io_service io_service;
udp::socket socket;
udp::endpoint receiver_endpoint;
boost::array<char, 1024> recv_buffer;
UDPClient();
void do_receive();
void handle_receive(const boost::system::error_code& error, size_t);
};
UDPClient::UDPClient()
: io_service(),
socket(io_service, {udp::v4(), 8888})
{
do_receive();
io_service.run();
}
void UDPClient::do_receive()
{
socket.async_receive_from(boost::asio::buffer(recv_buffer), receiver_endpoint,
boost::bind(&UDPClient::handle_receive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void UDPClient::handle_receive(const boost::system::error_code& error, size_t bytes_transferred)
{
std::cout << "ulala" << std::endl;
std::cout << "Received: '" << std::string(recv_buffer.begin(), recv_buffer.begin()+bytes_transferred) << "'\n";
if (!error || error == boost::asio::error::message_size)
do_receive();
}
int main()
{
UDPClient updclient;
}
This also prints the message received (assuming it is printable). See
for a way to make it possible to handle multiple UDP requests concurrently.
Upvotes: 5