|
Boost Users : |
Subject: Re: [Boost-users] boost::asio::asyn_accept handler
From: Christopher Pisz (christopherpisz_at_[hidden])
Date: 2017-03-28 14:24:03
I don't understand.
I want pass around the function object to be called back, because A) I want
the connection class itself to maintain its state B) The connection class
owns the socket and GetSocket() rubs me wrong. C) The server class has
create another connection class and tell it to listen OnAccept.
The problem is, as soon as you introduce std::function to hold it.
Here is a whole listing based purely on the example that works and compiles
fine:
//--------------------------------------
//
// server.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot
com)
//
// Distributed under the Boost Software License, Version 1.0. (See
accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include <ctime>
#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
std::string make_daytime_string()
{
using namespace std; // For time_t, time and ctime;
time_t now = time(0);
return ctime(&now);
}
class tcp_connection
: public boost::enable_shared_from_this<tcp_connection>
{
public:
typedef boost::shared_ptr<tcp_connection> pointer;
static pointer create(boost::asio::io_service& io_service)
{
return pointer(new tcp_connection(io_service));
}
tcp::socket& socket()
{
return socket_;
}
void start()
{
message_ = make_daytime_string();
boost::asio::async_write(socket_, boost::asio::buffer(message_),
boost::bind(&tcp_connection::handle_write, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
private:
tcp_connection(boost::asio::io_service& io_service)
: socket_(io_service)
{
}
void handle_write(const boost::system::error_code& /*error*/,
size_t /*bytes_transferred*/)
{
}
tcp::socket socket_;
std::string message_;
};
class tcp_server
{
public:
tcp_server(boost::asio::io_service& io_service)
: acceptor_(io_service, tcp::endpoint(tcp::v4(), 13))
{
start_accept();
}
private:
void start_accept()
{
tcp_connection::pointer new_connection =
tcp_connection::create(acceptor_.get_io_service());
auto callback = std::bind(&tcp_server::handle_accept, this,
new_connection, std::placeholders::_1);
acceptor_.async_accept(new_connection->socket(), callback);
}
void handle_accept(tcp_connection::pointer new_connection,
const boost::system::error_code& error)
{
if (!error)
{
new_connection->start();
}
start_accept();
}
tcp::acceptor acceptor_;
};
int main()
{
try
{
boost::asio::io_service io_service;
tcp_server server(io_service);
io_service.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
//--------------------------------------
Now change auto to std::function and it no longer compiles:
void start_accept()
{
tcp_connection::pointer new_connection =
tcp_connection::create(acceptor_.get_io_service());
std::function<void (tcp_connection::pointer new_connection, const
boost::system::error_code & error)> callback =
std::bind(&tcp_server::handle_accept, this, new_connection,
std::placeholders::_1);
acceptor_.async_accept(new_connection->socket(), callback);
}
//------------------------------------
So, how do I store the callback, such that I can pass it around?
Because, my goal is to move this the code in "tcp_server::start_accept" to
"tcp_connection::Listen" and just have tcp_server::start that calls
tcp_connection::Listen
-- View this message in context: http://boost.2283326.n4.nabble.com/boost-asio-asyn-accept-handler-tp4693107p4693146.html Sent from the Boost - Users mailing list archive at Nabble.com.
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net