Anum Sheraz
Anum Sheraz

Reputation: 2635

can't receive data from socket_.async_receive_from

I have created async functions start_receive() and start_send() inside my udp_server class. But by code doesn't stops and waits on "async_receive_from" line. Here's my code;

class udp_server
{
public:
  udp_server(boost::shared_ptr< boost::asio::io_service > io_service,
        const std::string& host,
        const std::string& port
    ) : io_service_(*io_service), socket_(*io_service, udp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 7777))
  {
        udp::resolver resolver(io_service_);
        udp::resolver::query query(udp::v4(), host, port);
        udp::resolver::iterator iter = resolver.resolve(query);
        endpoint_ = *iter;
        std::cout << "end point>>" << endpoint_ << std::endl;
        //start_receive();
  }

void start_receive()
  {
  std::cout << "Gotin>>start_receive" << std::endl;
  //std::cout << "Gotin>>" << std::endl;
    socket_.async_receive_from(
          boost::asio::buffer(recv_buffer_), remote_endpoint_,
          boost::bind(&udp_server::handle_receive, this,
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred
          ));
  }

  void handle_receive(const boost::system::error_code& error, std::size_t msg_len)
  {
  using namespace std;
    std::cout << "Got>> handle_receive" << std::endl;
    //size_t data_length = data.size();
    //std::cout.write(recv_buffer_.data(), recv_buffer_.size());
    if (!error || error == boost::asio::error::message_size)
    {
        //std::cout << "msg_len:" << msg_len << std::endl;
        std::cout.write(recv_buffer_.data(), msg_len);
        std::cout << ", " << msg_len << std::endl;
        start_send(recv_buffer_.data(), msg_len);
        recv_buffer_.assign(0);
        start_receive();
    }
  }

  void start_send(const std::string& msg, std::size_t msg_len)
  {
        socket_.async_send_to(boost::asio::buffer(msg, msg_len), remote_endpoint_,
          boost::bind(&udp_server::handle_send, this, msg,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));
  }

  void handle_send(const std::string& msg/*message*/,
       const boost::system::error_code& /*error*/,
       std::size_t tx_size/*bytes_transferred*/)
  {
        std::cout << "send>" << msg << std::endl;
        //std::cout << "size>" << tx_size << std::endl;
        //std::cout << "send>" << msg << std::endl;
  }

private:
  boost::asio::io_service& io_service_;
  udp::endpoint endpoint_;
  udp::socket socket_;
  udp::endpoint remote_endpoint_;
  boost::array<char, 1000> recv_buffer_;
};

int main()
{
  try
  {

    boost::shared_ptr< boost::asio::io_service > io_service(new boost::asio::io_service);

    udp_server server(io_service, "localhost", "6666");
    //boost::asio::io_service io_service;
    //udp_server server(io_service);
    //io_service.run();
    boost::thread_group tgroup;
    tgroup.create_thread( boost::bind(&udp_server::start_receive, &server));
    tgroup.join_all();
  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }

  return 0;
}

on the console, I get the line "Gotin>>start_receive" printed but the code suddenly gets terminated. As it should receive for some bytes to get received on line "socket_.async_receive_from(", but it doesn't. I never get to see "Got>> handle_receive" on console. what am I missing ?

Upvotes: 1

Views: 248

Answers (1)

bobah
bobah

Reputation: 18864

You should be giving threads to the io_service.run(), not to socket_.async_receive_from().

Your code would be something like:

tgroup.create_thread([&]{ io_service->run(); }); // or bind(&io_service::run, io_service)
io_service.dispatch([&]{ server.start_receive(); }); // or bind(&udp_server::start_receive, &server)
tgroup.join_all();

On a side note - you don't store io_service into a shared pointer. There is no shared ownership in your program.

Upvotes: 1

Related Questions