123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- //
- // 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 <cstdlib>
- #include <iostream>
- #define BOOST_PHOENIX_NO_PREDEFINED_TERMINALS
- #include <boost/phoenix.hpp>
- #include <boost/asio.hpp>
- 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 <typename Acceptor, typename Socket, typename Handler>
- 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<struct action_key>::type action;
- #include <boost/function.hpp>
- int main(int argc, char* argv[])
- {
- try
- {
- if (argc != 2)
- {
- std::cerr << "Usage: async_tcp_echo_server <port>\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<void(boost::system::error_code const &)> 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<void(boost::system::error_code const &, std::size_t)> read_handler;
- boost::function<void(boost::system::error_code const &, std::size_t)> 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;
- }
|