// // Copyright (c) 2011 Thomas Heller // // 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 #include #define BOOST_PHOENIX_NO_PREDEFINED_TERMINALS #include #include namespace phx = boost::phoenix; using boost::phoenix::ref; BOOST_PHOENIX_ADAPT_FUNCTION(void, read, boost::asio::async_read, 4) BOOST_PHOENIX_ADAPT_FUNCTION(void, write, boost::asio::async_write, 3) BOOST_PHOENIX_ADAPT_FUNCTION(boost::asio::mutable_buffers_1, buffer, boost::asio::buffer, 2) template void accept_impl(Acceptor & acceptor, Socket & socket, Handler const & handler) { acceptor.async_accept(socket, handler); } BOOST_PHOENIX_ADAPT_FUNCTION(void, accept, accept_impl, 3) typedef phx::expression::local_variable::type action; #include int main(int argc, char* argv[]) { try { if (argc != 2) { std::cerr << "Usage: async_tcp_echo_server \n"; return 1; } phx::lambda_type lambda; phx::arg_names::_1_type _1; boost::asio::io_service io_service; boost::asio::ip::tcp::acceptor acceptor(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), std::atoi(argv[1]))); boost::asio::ip::tcp::socket socket(io_service); std::size_t const max_length = 1024; char buf[max_length]; std::cout << "server starting...\n"; boost::function accept_handler; phx::expression::argument<1>::type _error; phx::expression::argument<2>::type _length; action _action; BOOST_AUTO( create_handler , (lambda(_action = lambda[_1]) [ if_(!_error) [ bind(_action, ref(socket), ref(buf), _error, _length) ] .else_ [ bind(&boost::asio::ip::tcp::socket::close, ref(socket)) , accept(ref(acceptor), ref(socket), phx::ref(accept_handler)) ] ]) ); boost::function read_handler; boost::function write_handler; accept_handler = if_(!_error) [ read(ref(socket), buffer(ref(buf), max_length), boost::asio::transfer_at_least(1), phx::ref(read_handler)) ]; { phx::expression::argument<1>::type _socket; phx::expression::argument<2>::type _buf; phx::expression::argument<3>::type _error; phx::expression::argument<4>::type _length; read_handler = create_handler( write(_socket, buffer(_buf, _length), phx::ref(write_handler)) ); write_handler = create_handler( read(_socket, buffer(_buf, max_length), boost::asio::transfer_at_least(1), phx::ref(read_handler)) ); } acceptor.async_accept( socket , accept_handler ); io_service.run(); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } return 0; }