0
votes

I tried to make an asynchronous UDP client using boost::asio I get some code on internet, and I managed to send message. But my client didn't received the message from the server ( and it works when i don't use boost ).

Here's my code

 class udp_async_client 
 {
 public:

   udp_async_client (boost::asio::io_service& io_service, std::string& host, std:: string port, char **av , int ac)
: reply ()
, _io_service (io_service)
, _sock (io_service, udp:: endpoint (udp:: v4 (), 0)) {

udp:: resolver resolver (_io_service);
udp:: resolver:: query query (udp:: v4 (), host, port);
udp:: resolver:: iterator endpoint_iterator = resolver.resolve (query);
sender_endpoint = *endpoint_iterator;

_io_service.run ();

//test request string                                                                                                                                                                                                                    
using namespace std;


std::string request = av[3];
for (int i = 4 ; i < ac ; ++i)
  {
    request += ";";
    request += av[i];
  }

std:: cout <<"Request is:" <<request <<std:: endl;



_sock.async_send_to (boost:: asio:: buffer (request.c_str(), request.length())
                     , sender_endpoint
                     , boost:: bind (&udp_async_client::handle_send_to_server
                                     , this, boost:: asio:: placeholders:: error
                                     , endpoint_iterator));

  }

 ~udp_async_client () {
_io_service.stop ();
  }

  void handle_receive_from (const boost::system::error_code& error,
                        size_t bytes_recvd) {}

  void handle_receive_from (const boost::system::error_code& error,
                        size_t bytes_recvd) {}

  void handle_send_to_server (const boost::system::error_code& e,
                          udp:: resolver:: iterator endpoint_iterator) {
std:: cout <<"Handle send to" <<std:: endl;
char reply [max_length] = {};
_sock.async_receive_from (
                          boost:: asio:: buffer (reply, max_length), sender_endpoint,
                          boost:: bind (&udp_async_client::handle_receive_from, this,
                                        boost:: asio:: placeholders:: error,
                                        boost::asio::placeholders::bytes_transferred));

std:: cout <<"Reply is:" <<reply <<std:: endl;
  }

private:
char reply [max_length];
boost::asio::io_service& _io_service;
udp:: socket _sock;
boost:: asio:: ip:: udp:: endpoint sender_endpoint;

};

and my main :

int main (int ac, char** av) {

  if (ac < 5) {
   std:: cerr <<"Usage: nonblocking_udp_echo_client <host> <port> <name> <name to reach> \n";
 return 1;
 }

  boost:: asio:: io_service io_service;
  std:: string host (av[1]);
  std:: string port (av[2]);

  while (true)
    {
     udp_async_client cli (io_service, host, port, av , ac);
     boost:: this_thread:: sleep (boost:: posix_time:: millisec (500));
   }
 return 0;
  }

I don't know what i did wrong ...

1
I'm surprised that compiles at all, since you have two handle_receive_from functions. An even bigger problem is that you are using a local variable as buffer for the reply in handle_send_to_server, after handle_send_to_server returns that buffer is no longer valid. - Some programmer dude
there's a working asynchronous UDP example here. - default
I never pass in handle_send_to_server for the moment . the only thing that is displayed is "Request is [...] " - kavaliero
It's a server example but I think i'll do this anyway - kavaliero

1 Answers

3
votes

_io_service.run() is a blocking call. Your code is actually not passing that line until the stop is called on io_service.